提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
ttf字体在不同大小下回自动计算对应大小下的轮廓,可是最终显示到计算机屏幕上还是需要进行光栅化。在低像素下编有可能出现有些像素块对应不满一个格子的情况。就像下图一样:
而hint(提示)技术就是想通过抗锯齿和网格对齐的方式来使这种情况减少。
在freetype2中,字体往往可以被autohint(自动)来获取不错的效果。
在cocos2dx源码中有类似这样的层级(label使用ttf或者textfieldttf):
[label]
visit();
updateContent();
alignText();
[FontAtlas]
prepareLetterDefinitions();
[CCFontFreeType]
getGlyphBitmap();
[freetype]
FT_Load_Char()
而bitmap,用于保存每个像素深度值的数组便由FT_Load_Char()产生。cocos2dx随后便通过这个bitmap和相关的输出信息来生成对应的材质。而cocos2dx在使用FT_Load_Char()时吧autohint给关了,具体原因未知。于是我就试着把这个参数给设置为打开(将LOAD_NO_AUTOHINT标记去掉),好在改这个cpp所用重新编译时间不长。
打开后发现情况并没有好了很多,虽然半透明块减少了很多,但是仍然有不少,而且部分地方出现了线条大小不一的情况。于是log输出了一下对应的bitmap值。结果却是有缺项。便又去看了看cocos2dx是如何设置对应参数生成bitmap的。随后发现最终生成的bitmap大小和之前调用的FT_SET_CHAR_SIZE有关,具体是写为固定为dpi的(72)和fontsize变量。但是不管调大fontsize和dpi对应的值,其最终渲染出来的字都会变大。于是便想到手动写一个类继承了TextFieldTTF,并将fontSize调大生成更高清的bitmap,但同时又通过管理scale来让字体大小和原来一样。
#include "ui-UiTextFieldTTFNA.h"
Label * UiTextFieldTTFNA::create()
{
CC_ASSERT(false, "");
return nullptr;
}
float UiTextFieldTTFNA::getScale() const
{
return Node::getScale() * _precisionScale;
}
void UiTextFieldTTFNA::setScale(float scale)
{
Node::setScale(scale / _precisionScale);
}
float UiTextFieldTTFNA::getPrecisionScale() const
{
return _precisionScale;
}
void UiTextFieldTTFNA::setPrecisionScale(float scale)
{
auto fontSize = getFontSize();
auto fontScale = getScale();
_precisionScale = scale;
setFontSize(fontSize);
setScale(fontScale);
}
float UiTextFieldTTFNA::getFontSize() const
{
auto oldConfig = getTTFConfig();
auto fontSize = oldConfig.fontSize;
return fontSize / _precisionScale;
}
void UiTextFieldTTFNA::setFontSize(float sizes)
{
auto oldConfig = getTTFConfig();
auto fontName = oldConfig.fontFilePath;
auto fontSize = sizes * _precisionScale;
TTFConfig ttfConfig(fontName, fontSize, GlyphCollection::DYNAMIC);
setTTFConfig(ttfConfig);
}
void UiTextFieldTTFNA::draw(Renderer * renderer, const Mat4 & transform, uint32_t flags)
{
for (auto batchNode : _batchNodes){
auto texture0 = batchNode->getTextureAtlas()->getTexture();
auto texture1 = batchNode->getTexture();
texture0->setAliasTexParameters();
texture1->setAliasTexParameters();
}
TextFieldTTF::draw(renderer, transform, flags);
}
UiTextFieldTTFNA * UiTextFieldTTFNA::textFieldWithPlaceHolder(const std::string & placeholder, const Size & dimensions, TextHAlignment alignment, const std::string & fontName, float fontSize)
{
UiTextFieldTTFNA *ret = new (std::nothrow) UiTextFieldTTFNA();
if (ret && ret->initWithPlaceHolder("", dimensions, alignment, fontName, fontSize))
{
ret->_precisionScale = 1.0f;
ret->setPrecisionScale(3);
ret->autorelease();
if (placeholder.size() > 0)
{
ret->setPlaceHolder(placeholder);
}
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}
UiTextFieldTTFNA * UiTextFieldTTFNA::textFieldWithPlaceHolder(const std::string & placeholder, const std::string & fontName, float fontSize)
{
UiTextFieldTTFNA *ret = new (std::nothrow) UiTextFieldTTFNA();
if (ret && ret->initWithPlaceHolder("", fontName, fontSize))
{
ret->_precisionScale = 1.0f;
ret->setPrecisionScale(3);
ret->autorelease();
if (placeholder.size() > 0)
{
ret->setPlaceHolder(placeholder);
}
return ret;
}
CC_SAFE_DELETE(ret);
return nullptr;
}