-
Creator 版本:2.1.0
-
目标平台: PC
我们发现 把项目发布PC 版本之后非常卡顿,目前大致找到一个问题是我们用了一个自己的字体库,使用系统自带的字体就不卡顿,我们使用lua 的版本同样的字体就不卡顿 请问这个是什么问题
看了代码 当一个字体改变大小和颜色 的时候都会频繁的移除和添加字体,我感觉应该可以修改为当字体发生变化的时候在做这个操作,而不是一些简单的属性发生变化都去删除和添加字体
Creator 版本:2.1.0
目标平台: PC
我们发现 把项目发布PC 版本之后非常卡顿,目前大致找到一个问题是我们用了一个自己的字体库,使用系统自带的字体就不卡顿,我们使用lua 的版本同样的字体就不卡顿 请问这个是什么问题
看了代码 当一个字体改变大小和颜色 的时候都会频繁的移除和添加字体,我感觉应该可以修改为当字体发生变化的时候在做这个操作,而不是一些简单的属性发生变化都去删除和添加字体
官方大大有解决方案吗?
经过几天的奋斗发现了大致bug 的地方,
void updateFont(const std::string& fontName, float fontSize, bool bold = false)
{
bool bRet = false;
do
{
_fontName = fontName;
_fontSize = fontSize;
std::string fontPath;
HFONT hDefFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT);
LOGFONTA tNewFont = { 0 };
LOGFONTA tOldFont = { 0 };
GetObjectA(hDefFont, sizeof(tNewFont), &tNewFont);
if (!_fontName.empty())
{
// firstly, try to create font from ttf file
const auto& fontInfoMap = getFontFamilyNameMap();
auto iter = fontInfoMap.find(_fontName);
if (iter != fontInfoMap.end())
{
fontPath = iter->second;
std::string tmpFontPath = fontPath;
int nFindPos = tmpFontPath.rfind("/");
tmpFontPath = &tmpFontPath[nFindPos + 1];
nFindPos = tmpFontPath.rfind(".");
// IDEA: draw ttf failed if font file name not equal font face name
// for example: "DejaVuSansMono-Oblique" not equal "DejaVu Sans Mono" when using DejaVuSansMono-Oblique.ttf
_fontName = tmpFontPath.substr(0, nFindPos);
}
else
{
auto nFindPos = fontName.rfind("/");
if (nFindPos != fontName.npos)
{
if (fontName.length() == nFindPos + 1)
{
_fontName = "";
}
else
{
_fontName = &_fontName[nFindPos + 1];
}
}
}
tNewFont.lfCharSet = DEFAULT_CHARSET;
strcpy_s(tNewFont.lfFaceName, LF_FACESIZE, _fontName.c_str());
}
if (_fontSize)
{
tNewFont.lfHeight = -_fontSize;
}
if (bold)
{
tNewFont.lfWeight = FW_BOLD;
}
else
{
tNewFont.lfWeight = FW_NORMAL;
}
GetObjectA(_font, sizeof(tOldFont), &tOldFont);
if (tOldFont.lfHeight == tNewFont.lfHeight
&& tOldFont.lfWeight == tNewFont.lfWeight
&& 0 == strcmp(tOldFont.lfFaceName, tNewFont.lfFaceName))
{
bRet = true;
break;
}
// delete old font
// 导致卡顿的地方1
// 增加逻辑 当字体没有没有变换的时候不需要 移除
_removeCustomFont();
if (fontPath.size() > 0)
{
_curFontPath = fontPath;
wchar_t * pwszBuffer = _utf8ToUtf16(_curFontPath);
if (pwszBuffer)
{
// 导致卡顿的地方2
// 增加逻辑 当字体没有没有变换的时候不需要 移除
if (AddFontResource(pwszBuffer))
{
SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
}
delete[] pwszBuffer;
pwszBuffer = nullptr;
}
}
_font = nullptr;
// disable Cleartype
tNewFont.lfQuality = ANTIALIASED_QUALITY;
// create new font
_font = CreateFontIndirectA(&tNewFont);
if (!_font)
{
// create failed, use default font
_font = hDefFont;
break;
}
else
{
SelectObject(_DC, _font);
SendMessage(_wnd, WM_FONTCHANGE, 0, 0);
}
bRet = true;
} while (0);
}
void CanvasRenderingContext2D::set_font(const std::string& font)
{
if (_font != font)
{
_font = font;
std::string boldStr;
std::string fontName = "Arial";
std::string fontSizeStr = "30";
// support get font name from `60px American` or `60px "American abc-abc_abc"`
std::regex re("(bold)?\\s*((\\d+)([\\.]\\d+)?)px\\s+([\\w-]+|\"[\\w -]+\"$)");
std::match_results<std::string::const_iterator> results;
if (std::regex_search(_font.cbegin(), _font.cend(), results, re))
{
boldStr = results[1].str();
fontSizeStr = results[2].str();
fontName = results[5].str();
}
float fontSize = atof(fontSizeStr.c_str());
//SE_LOGD("CanvasRenderingContext2D::set_font: %s, Size: %f, isBold: %b\n", fontName.c_str(), fontSize, !boldStr.empty());
// 这个是调用的地方
_impl->updateFont(fontName, fontSize, !boldStr.empty());
}
}