📄 gnewfont_chn.cc
字号:
//-----------------------------------------------------------------------------
// Torque Game Engine
// Copyright (C) GarageGames.com, Inc.
//-----------------------------------------------------------------------------
#include "platform/platform.h"
#include "platform/platformFont.h"
#include "platform/profiler.h"
#include "platform/platformMutex.h"
#include "console/console.h"
#include "core/stream.h"
#include "dgl/gBitmap.h"
#include "core/fileStream.h"
#include "core/findMatch.h"
#include "dgl/gTexManager.h"
#include "dgl/gNewFont.h"
#include "util/safeDelete.h"
#include "core/frameAllocator.h"
#include "core/unicode.h"
#include "zlib.h"
//////////////////////////////////////////////////////////////////////////
/// Chinese
#ifdef TGE_CHINESE
//////////////////////////////////////////////////////////////////////////
U32 GFont::getStrNWidth(const UTF8 *str, U32 n)
{
AssertFatal(str != NULL, "GFont::getStrNWidth: String is NULL");
if (str == NULL || str[0] == NULL || n == 0)
return 0;
U32 totWidth = 0;
UTF16 curChar;
U32 charCount;
for(charCount = 0; charCount <= n; charCount++)
{
curChar = GBSTEPN(str,charCount);
if(curChar == NULL)
break;
if(isValidChar(curChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(curChar);
totWidth += rChar.xIncrement;
}
else if (curChar == dT('\t'))
{
const PlatformFont::CharInfo& rChar = getCharInfo(dT(' '));
totWidth += rChar.xIncrement * TabWidthInSpaces;
}
}
return(totWidth);
}
U32 GFont::getStrNWidth(const UTF16 *str, U32 n)
{
AssertFatal(str != NULL, "GFont::getStrNWidth: String is NULL");
if (str == NULL || str[0] == NULL || n == 0)
return 0;
U32 totWidth = 0;
UTF16 curChar;
U32 charCount;
for(charCount = 0; charCount <= n; charCount++)
{
curChar = str[charCount];
if(curChar == NULL)
break;
if(isValidChar(curChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(curChar);
totWidth += rChar.xIncrement;
}
else if (curChar == dT('\t'))
{
const PlatformFont::CharInfo& rChar = getCharInfo(dT(' '));
totWidth += rChar.xIncrement * TabWidthInSpaces;
}
}
return(totWidth);
}
U32 GFont::getStrNWidthPrecise(const UTF8 *str, U32 n)
{
AssertFatal(str != NULL, "GFont::getStrNWidth: String is NULL");
if (str == NULL || str[0] == NULL || n == 0)
return(0);
U32 totWidth = 0;
UTF16 curChar;
U32 charCount = 0;
for(charCount = 0; charCount < n; charCount++)
{
curChar = GBSTEPN(str,charCount);
if(curChar == NULL)
break;
if(isValidChar(curChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(curChar);
totWidth += rChar.xIncrement;
}
else if (curChar == dT('\t'))
{
const PlatformFont::CharInfo& rChar = getCharInfo(dT(' '));
totWidth += rChar.xIncrement * TabWidthInSpaces;
}
}
UTF16 endChar = str[getMin(charCount,n-1)];
if (isValidChar(endChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(endChar);
if (rChar.width > rChar.xIncrement)
totWidth += (rChar.width - rChar.xIncrement);
}
return(totWidth);
}
U32 GFont::getStrNWidthPrecise(const UTF16 *str, U32 n)
{
AssertFatal(str != NULL, "GFont::getStrNWidth: String is NULL");
if (str == NULL || str[0] == NULL || n == 0)
return(0);
U32 totWidth = 0;
UTF16 curChar;
U32 charCount = 0;
for(charCount = 0; charCount < n; charCount++)
{
curChar = str[charCount];
if(curChar == NULL)
break;
if(isValidChar(curChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(curChar);
totWidth += rChar.xIncrement;
}
else if (curChar == dT('\t'))
{
const PlatformFont::CharInfo& rChar = getCharInfo(dT(' '));
totWidth += rChar.xIncrement * TabWidthInSpaces;
}
}
UTF16 endChar = str[getMin(charCount,n-1)];
if (isValidChar(endChar))
{
const PlatformFont::CharInfo& rChar = getCharInfo(endChar);
if (rChar.width > rChar.xIncrement)
totWidth += (rChar.width - rChar.xIncrement);
}
return(totWidth);
}
inline bool cIslbracket (const U16 c){return c=='{' || c=='[' || c=='〈' || c=='《' || c=='(' || c=='『' || c=='〖' || c=='【' || c=='「';}
inline bool cIsrbracket (const U16 c){return c=='}' || c==']' || c=='〉' || c=='》' || c==')' || c=='』' || c=='〗' || c=='】' || c=='」' ;}
inline bool cIsbracket (const U16 c){return dIslbracket(c) || dIsrbracket(c);}
inline bool cIsrquote (const U16 c){return c=='’' || c=='”';}
inline bool cIslquote (const U16 c){return c=='‘' || c=='“';}
inline bool cIsquote (const U16 c){return cIsrquote(c) || cIslquote(c);}
inline bool cIssep (const U16 c){return c==','|| c==';'|| c=='?' || c=='。'|| c=='!' || c=='.' || c=='˙'|| c==':' || c=='、';}
inline bool IsCantHeaderOpr(const U16 c)
{
if(!IsGB(c))
{
if(dIssep(c) || dIsrbracket(c))
return true;
}
else
{
U16 w = MAKEU16(HU8(c), LU8(c));
if(cIssep(w) || cIsrbracket(w) || cIsrquote(c))
return true;
}
return false;
}
U32 GFont::getBreakPos(const UTF8 *str, U32 slen, U32 width, bool breakOnWhitespace)
{
// Some early out cases.
if(slen==0)
return 0;
U32 ret = 0;
U32 lastws = 0;
U32 m;
UTF16 c;
// convert the buffer to utf16, converter will give us the length.
for(; ret < slen; ret++)
{
c = GBSTEPN(str,ret);
if(c == 0)
break;
if(c == dT('\t'))
c = dT(' ');
if(!isValidChar(c))
{
//ret++;
continue;
}
if(c == dT(' '))
lastws = ret+1;
const PlatformFont::CharInfo& rChar = getCharInfo(c);
if(rChar.width > width || rChar.xIncrement > width)
{
if(lastws && breakOnWhitespace)
{
ret = lastws;
goto laEnd;
}
//return lastws;
if(IsGB(c))//GBSTEPN已递增1,现需要倒回
ret--;
goto laEnd;
//return ret;
}
width -= rChar.xIncrement;
// ret++;
}
laEnd:
if(ret < slen)
{
//查找英语单词是否被break了
if(dIsalnum(str[ret]))
{
for(m=ret-1; m >= 0; m--)
{
c = str[m];
if(!dIsalnum(c))
break;
}//for
if(m > 0)
{
ret = m+1;
}
}//if
for(m=ret; m < slen; m++)
{
c = GBSTEPN(str,m);
if(c == NULL)
break;
if(!IsCantHeaderOpr(c))
{
if(IsGB(c))//GBSTEPN已递增1,现需要倒回
m--;
break;
}
}//for
if(m>=ret)
ret = m;
}
return ret;
}
U32 GFont::getBreakPos(const UTF16 *str, U32 slen, U32 width, bool breakOnWhitespace)
{
// Some early out cases.
if(slen==0)
return 0;
U32 ret = 0;
U32 lastws = 0;
S32 m;
UTF16 c;
// convert the buffer to utf16, converter will give us the length.
for(; ret < slen; ret++)
{
c = str[ret];
if(c == 0)
break;
if(c == dT('\t'))
c = dT(' ');
if(!isValidChar(c))
{
//ret++;
continue;
}
if(c == dT(' '))
lastws = ret+1;
const PlatformFont::CharInfo& rChar = getCharInfo(c);
if(rChar.width > width || rChar.xIncrement > width)
{
// if(lastws && breakOnWhitespace)
// return lastws;
//return ret;
if(lastws && breakOnWhitespace)
{
ret = lastws;
goto laEnd;
}
goto laEnd;
}
width -= rChar.xIncrement;
// ret++;
}
laEnd:
if(ret < slen)
{
//查找英语单词是否被break了
if( !IsGB(str[ret]) && dIsalnum(str[ret]))
{
for(m=ret-1; m >= 0; m--)
{
c = str[m];
if(IsGB(c) || !dIsalnum(c))
break;
}//for
if(m > 0)
ret = m+1;
}//if
//查找不能出现在行首的点符号
for(m=ret; m < slen; m++)
{
c = str[m];
if(c == 0)
break;
if(!IsCantHeaderOpr(c))
break;
}//for
if(m>ret)
ret = m;
}
return ret;
}
void GFont::wrapString(const UTF8 *txt, U32 lineWidth, Vector<U32> &startLineOffset, Vector<U32> &lineLen)
{
Con::errorf("GFont::wrapString(): Not yet converted to be UTF-8 safe");
startLineOffset.clear();
lineLen.clear();
if (!txt || !txt[0] || lineWidth < getCharWidth('W')) //make sure the line width is greater then a single character
return;
U32 len = dStrlen(txt);
UTF16 c;
U32 startLine;
for (U32 i = 0; i < len;)
{
startLine = i;
startLineOffset.push_back(startLine);
// loop until the string is too large
bool needsNewLine = false;
U32 lineStrWidth = 0;
for (; i < len; i++)
{
c = GBSTEPN(txt,i);
if(isValidChar(c))
{
lineStrWidth += getCharInfo(c).xIncrement;
if ( c == '\n' || lineStrWidth > lineWidth )
{
needsNewLine = true;
break;
}
}
}
if (!needsNewLine)
{
// we are done!
lineLen.push_back(i - startLine);
return;
}
// now determine where to put the newline
// else we need to backtrack until we find a either space character
// or \\ character to break up the line.
S32 j;
for (j = i - 1; j >= startLine; j--)
{
if (dIsspace(txt[j]))
break;
}
if (j < startLine)
{
// the line consists of a single word!
// So, just break up the word
j = i - 1;
}
lineLen.push_back(j - startLine);
i = j;
// now we need to increment through any space characters at the
// beginning of the next line
for (i++; i < len; i++)
{
if (!dIsspace(txt[i]) || txt[i] == '\n')
break;
}
}
}
void GFont::wrapString(const UTF16 *txt, U32 lineWidth, Vector<U32> &startLineOffset, Vector<U32> &lineLen)
{
Con::errorf("GFont::wrapString(): Not yet converted to be UTF-8 safe");
startLineOffset.clear();
lineLen.clear();
if (!txt || !txt[0] || lineWidth < getCharWidth('W')) //make sure the line width is greater then a single character
return;
U32 len = dStrlen(txt);
UTF16 c;
U32 startLine;
for (U32 i = 0; i < len;)
{
startLine = i;
startLineOffset.push_back(startLine);
// loop until the string is too large
bool needsNewLine = false;
U32 lineStrWidth = 0;
for (; i < len; i++)
{
c = txt[i];
if(isValidChar(c))
{
lineStrWidth += getCharInfo(c).xIncrement;
if ( c == '\n' || lineStrWidth > lineWidth )
{
needsNewLine = true;
break;
}
}
}
if (!needsNewLine)
{
// we are done!
lineLen.push_back(i - startLine);
return;
}
// now determine where to put the newline
// else we need to backtrack until we find a either space character
// or \\ character to break up the line.
S32 j;
for (j = i - 1; j >= startLine; j--)
{
if (dIsspace(txt[j]))
break;
}
if (j < startLine)
{
// the line consists of a single word!
// So, just break up the word
j = i - 1;
}
lineLen.push_back(j - startLine);
i = j;
// now we need to increment through any space characters at the
// beginning of the next line
for (i++; i < len; i++)
{
if (!dIsspace(txt[i]) || txt[i] == '\n')
break;
}
}
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -