需求描述:
有两个字符串, 需要根据最长的串求出一个合理的大小, 这个大小等于最长串大小, 并绘制成分式效果, 默认 一个汉字占 三个utf8字符,一个字母占1个 , 直接跟strlen 计算长度将不准确.
真实效果如图:
要计算中间串占用长度先得分以下三步:
1: UTF8 的中英文混合串 转为UNICODE 字符串;
2: 区分中文和英文, 分别计算大小;
3: 将所有字符串组合直接用渲染引擎绘制(GDI,opengl等都可以);
代码如下:
utf8转unicode:
std::wstring utf82Unicode(const char* str){
libiconv_t h = 0;
if(sizeof(wchar_t) == 2)
h = iconv_open("UTF-16LE", codepage);
else if(sizeof(wchar_t) == 4)
h = iconv_open("UTF-32LE", codepage);
if (h == (iconv_t)(-1))
return 0;
char* pInput = (char*)str;
size_t nInput = nlen;
std::wstring wStr;
WStr.resize(nInput);
char* pOutput = (char*)WStr.data();
size_t nOutput = WStr.size() * sizeof(wchar_t);
size_t err = iconv(h, &pInput, &nInput, &pOutput, &nOutput);
if (err == 0)
WStr.resize((WStr.size() * sizeof(wchar_t) - nOutput) / sizeof(wchar_t));
else
WStr.clear();
iconv_close(h);
return WStr;
}
求混合串长度:
bool IsChChar(wchar_t no)
{
if (no >= 0x4E00 && no <= 0x9FA5)
return true;
return false;
}
// uni >= '0' && uni <= '9' (*s >= 'A' && *s <= 'Z') || (*s >= 'a' && *s <= 'z')
int CalcStringLength(string & str, int defaultChineseCharlen = 2)
{
std::wstring wstr1 = utf82Unicode(str.c_str());
int len = 0;
for (int i = 0; i < wstr1.size(); ++i)
{
if (IsChChar(wstr1[i]))
len += 2;
else
len += 1;
}
return len;
}
组合成一个串:
string ExpressionNode::BaseLineCalc(ExpressionNode * lineNode, string & v1, string & v2)
{
int len1 = CalcStringLength(v1->m_FdValue);
int len2 = CalcStringLength(v2->m_FdValue);
int len = len1 > len2 ? len1 : len2;
if (len == 0)
return "";
int blanksize = len1 > len2 ? (len1 - len2): (len2 - len1);
if (blanksize > 0)
{
string tmp("");
for (int i = 0; i < blanksize/2; i++)
{
tmp += " ";
}
GsString retStr("");
if (len1 > len2)
{
retStr += tmp;
retStr+= (v2->m_FdValue);
retStr += tmp;
v2->m_FdValue = retStr;
}
else
{
retStr += tmp;
retStr += (v1->m_FdValue);
retStr += tmp;
v1->m_FdValue = retStr;
}
}
string tmp = "\n";
for (int i = 0; i < len; i++)
tmp += "-";
tmp += "\n";
return tmp;
}