⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnewfont_chn.cc

📁 五行MMORPG引擎系统V1.0
💻 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 + -