Cocos2d-x 文字显示

Cocos2d-x 文字显示

声明:本文分析的是cocos2d-x-3.12的代码

cocos底层使用的是OpenGL进行页面渲染,但OpenGL并支持文字的处理,OpenGL主要是用于图像和3D模型的渲染。为了支持文字的渲染,cocos会将文字转换成要显示的图片,然后通过OpenGL把图片显示出来。

 

cocos2d-x 3.x中支持四种文字的处理,都实现在Lable类中,对应了Label的四种类型,        ttf字体TTF、美术字BMFONT、美术字CHARMAP、系统字 STRING_TEXTURE。对于STRING_TEXTURE系统字的Label实现,与其他三种Label有些不一样,系统字采用的是系统字体,cocos没有对应的字体实现,而其他三种Lbael都有对应的字体类型。

 

STRING_TEXTURE系统字Label

系统字的创建

可以通过Label类的以下静态函数创建。

static LabelcreateWithSystemFont(const  std::string& text, const  std::string& font, floatfontSize, const  Size& dimensions = Size::ZERO, TextHAlignment hAlignment = TextHAlignment::LEFT, TextVAlignment vAlignment = TextVAlignment::TOP);

参数: text显示的文字内容
font显示字体的名字。
fontSize字体大小

返回:返回的是一个Label类。

内容的更新

对于所有类型的Label创建完设置新文本后,不会立即生成相应的文字图片,创建的时候只是会设置一个Label需要更新的标志bool Label ::_contentDirty。当需要绘制Label时,如果发现Label内容需要更新则会调用Label::updateContent函数更新文本内容。

 

系统字Label::updateContent函数中会调用createSpriteForSystemFont函数,该函数会创建一个Texture2D纹理,并掉用Texture2D::initWithString函数初始化纹理,生成相应的文字图片。最后使用文字纹理生成一个sprite精灵,保存在Sprite * Label::_textSprite变量中。整个过程和以下几行代码类似:

    auto t = new (std::nothrow)Texture2D;

    t->initWithString("abcdefg", "Arial", 30);

    auto spt = Sprite::createWithTexture(t);

 

显示文字

系统字label是创建一个精灵,然后保存在Label::_textSprite中,所以显示系统中label时就是显示textSprite。以下时Label类绘制的代码。

void Label::drawSelf(bool visibleByCamera, Renderer* renderer, uint32_t flags)

{

    if (_textSprite)

    {

        if (_shadowNode)

        {

            _shadowNode->visit(renderer, _modelViewTransform, flags);

        }

        _textSprite->visit(renderer, _modelViewTransform, flags);

    }

    else if (visibleByCamera && !_utf8Text.empty())

    {

        draw(renderer, _modelViewTransform, flags);

    }

}

Label::drawSelf函数可以看出,如果是系统字则绘制textSprite,否则会调用draw函数绘制。

 

 

Font字体Label

字体Label根据不同字体的实现可以分为三种,分别是字体TTF、美术字BMFONT、美术字CHARMAP。这三种每一种都有对应一种字体实现。

 

TTF字体Label

TTF字体Label对应使用的字体类是FontFreeType类,该字体类接收一个*.ttf字体文件初始化,对应Label的类型是LabelType::BMFONT

Label的创建

Static Label * createWithTTF(const std::string& text, const std::string& fontFilePath, float fontSize, const Size& dimensions = Size::ZERO, TextHAlignment hAlignment = TextHAlignment::LEFT, TextVAlignment vAlignment = TextVAlignment::TOP);

static Label* createWithTTF(const TTFConfig& ttfConfig, const std::string& textTextHAlignment hAlignment = TextHAlignment::LEFT, int maxLineWidth = 0);

 

BMFONT美术字Label

美术字BMFONT的Label对应使用的字体类是FontFNT类,该类美术字由一个配置文件和一张图片组成,图片包含了所有字体中包含的文字,只需要包含几个需要的文字就行,配置文件会记录每个文字所在的位置和大小。FontFNT类只需要通过美术字的配置文件进行初始化就行了。这种美术字可以通过BMFont.exe等软件生成,软件会同时生成配置文件和相应的图片。对应的Label类型是LabelType::BMFONT

Label的创建

Static Label* createWithBMFont(const std::string& bmfontPath, const std::string& text, const TextHAlignment& hAlignment = TextHAlignment::LEFT, int maxLineWidth = 0, const Vec2& imageOffset = Vec2::ZERO);

 

CHARMAP美术字Label

CharMap美术字的Label对应的字体类型是FontCharMap类,该类使用的美术字是一张图片,图片上每个字的长宽都是一样的,且文字是按照ASCII顺序排列的。这类美术字通常可以用于数字的显示。对应的Label类型是LabelType::CHARMAP

 

Label的创建

Static Label * createWithCharMap(const std::string& charMapFile, int itemWidth, int itemHeight, int startCharMap);

Static Label * createWithCharMap(Texture2D* texture, int itemWidth, int itemHeight, int startCharMap);

Static Label * createWithCharMap(const std::string& plistFile);

 

字符编码

cocos2d-x中label字符使用的是使用的是unicode编码,创建label时要传入UTF-8字符,C++11起UTF-8字符串可以通过字符串前面添加u8来实现,如:u8"abc中文"。如果传入的不是UTF-8字符串,因为UTF-8兼容ASCII,所以对于英文不会有影响,但是对于中文来说就可能出现乱码或无法显示等等。

对于TTF字体的Label字体中必须包含相应的文字,否则会显示异常,例如使用英文字体显示中文时,中文就无法显示。

如下:


	//字体SourceHanSerifSC-Heavy.otf为一种宋体字,中文字体
	auto label = Label::createWithTTF(u8"Abc中文", "fonts/SourceHanSerifSC-Heavy.otf", 48);
	label->setPosition(visibleSize / 2);
	this->addChild(label);

	//字体arial.ttf为英文字体,不包括中文字符,所以中文显示异常
	auto label2 = Label::createWithTTF(u8"Abc中文", "fonts/arial.ttf", 48);
	label2->setPosition(visibleSize.width / 2, visibleSize.height / 2 - 50);
	this->addChild(label2);

	//没有使用 u8显示会出现乱码
	auto label3 = Label::createWithSystemFont("Abc中文", "宋体", 48);
	label3->setPosition(visibleSize.width / 2, visibleSize.height / 2 - 100);
	this->addChild(label3);

结果:

 

 

字体Font

字体的类图大致如下。

 

 

三种字体类FontFreeTypeFontFNTFontCharMap都是继承至Font。在Label中并不直接使用Font类,而是使用了一个代理类FontAtlas类。FontAtlas类实现了将字体转换成Texture的功能。为了防止同样字体的FontAltas重复创建,Cocos增加了一个FontAtlasCache类,该类有一个unordered_map静态变量,保存了系统中以创建的FontAtlas类。

 

在Label类中一个了FontAtlas变量FontAtlas* _fontAtlas,当创建Font类型的Label是,系统会创建一个相应的FontAtlas变量,并保存在fontAtlas变量中。

 

Font类中有一个接口函数createFontAtlas,该函数可以创建处相应Font类的FontAtlas,在FontAlts里面也会保存相应的字体。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值