hgeFontCN.cpp
上传用户:maxiaolivb
上传日期:2022-06-07
资源大小:915k
文件大小:5k
源码类别:

游戏引擎

开发平台:

Visual C++

  1. #include "hgefontcn.h"
  2. #include <stdlib.h>
  3. #include <stdio.h>
  4. HGE *hgeFontCN::hge=0;
  5. hgeFontCN::hgeFontCN(void)
  6. {
  7. }
  8. hgeFontCN::~hgeFontCN(void)
  9. {
  10. for(int i=0; i<HZ_HIGH_MAX; i++)
  11. {
  12. for(int j=0; j<HZ_LOW_MAX; j++)
  13. {
  14. if(letters[i][j])
  15. delete letters[i][j];
  16. }
  17. }
  18. if(hTexture)
  19. hge->Texture_Free(hTexture);
  20. hge->Release();
  21. }
  22. //根据字体文件创建
  23. hgeFontCN::hgeFontCN(const char *filename)
  24. {
  25. int tex_width; //纹理宽度
  26. int char_width; //字符宽度
  27. float texx; //纹理 X
  28. float texy; //纹理 Y
  29. hge=hgeCreate(HGE_VERSION);
  30. fScale=1.0f;
  31. fRot=0.0f;
  32. fTracking=0.0f;
  33. hTexture=0;
  34. fZ=0.5f;
  35. nBlend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE;
  36. dwCol=0xFFFFFFFF;
  37. st_FontCN_Head fonthead;
  38. FILE *pFontFile = fopen(filename,"r");
  39. if (pFontFile)
  40. {
  41. size_t filesize = 0;
  42. filesize = fread(&fonthead,1,sizeof(st_FontCN_Head),pFontFile);
  43. if (filesize != sizeof(st_FontCN_Head))
  44. {
  45. fclose(pFontFile);
  46. return;
  47. }
  48. // 文件头不正确
  49. if(strcmp(fonthead.strHead,"[HGEFONTCN]"))
  50. {
  51. fclose(pFontFile);
  52. return;
  53. }
  54. // 获得字模文件名
  55. char *imgfile = fonthead.strImgFileName;
  56. char szFullImgFile[_MAX_PATH];
  57. char drive[_MAX_DRIVE];
  58. char dir[_MAX_DIR];
  59. char fname[_MAX_FNAME];
  60. char ext[_MAX_EXT];
  61. _splitpath( filename, drive, dir, fname, ext );
  62. sprintf(szFullImgFile,"%s%s",dir,imgfile);
  63. // 加载指定字模图片
  64. hTexture = hge->Texture_Load(szFullImgFile);
  65. if(!hTexture)
  66. {
  67. fclose(pFontFile);
  68. return;
  69. }
  70. // 获得纹理宽度
  71. tex_width=hge->Texture_GetWidth(hTexture);
  72. // 获得字符宽度
  73. char_width = fonthead.dwFontWidth;
  74. fHeight = fonthead.dwFontHeight;
  75. ZeroMemory( &letters, sizeof(letters) );
  76. texx=texy=0.0f;
  77. filesize = 0;
  78. while(!feof(pFontFile))
  79. {
  80. st_FontCN_Body fontbody;
  81. filesize = fread(&fontbody,1,sizeof(st_FontCN_Body),pFontFile);
  82. if (filesize != sizeof(st_FontCN_Body))
  83. break;
  84. BYTE hz0 = fontbody.HZ[0];
  85. BYTE hz1 = fontbody.HZ[1];
  86. texx = (float)(fontbody.dwFontX);
  87. texy = (float)(fontbody.dwFontY);
  88. float char_w = char_width;
  89. // 读取汉字字模
  90. if(hz0 >= HZ_HIGH_FIX && hz0 <= HZ_HIGH_END)
  91. {
  92. hz0 -= HZ_HIGH_FIX;
  93. if(hz1 >= HZ_LOW_FIX && hz1 <= HZ_LOW_END)
  94. hz1 -= HZ_LOW_FIX;
  95. else
  96. continue;
  97. }
  98. // 读取标准ASCII字模
  99. else if (hz0 == 0xff)
  100. {
  101. hz0 = HZ_HIGH_MAX - VALUE_FIX;
  102. if(hz1 >= ASCII_FIX && hz1 < ASCII_END)
  103. hz1 -= ASCII_FIX;
  104. else
  105. continue;
  106. char_w = ASCII_WIDTH; //标准ASCII字模宽度
  107. }
  108. // 如果不是汉字也不是标准ASCII字模就读下一个
  109. else
  110. continue;
  111. letters[hz0][hz1] = new hgeSprite(hTexture, texx, texy, (float)char_w, fHeight);
  112. }
  113. fclose(pFontFile);
  114. }
  115. }
  116. //根据字体对象创建
  117. hgeFontCN::hgeFontCN(const hgeFontCN &fnt)
  118. {
  119. }
  120. //绘制字符串
  121. void hgeFontCN::Render(float x, float y, const char *string)
  122. {
  123. float fx=x;
  124. while(*string)
  125. {
  126. BYTE hz0 = *string;
  127. BYTE hz1 = *(string+1);
  128. // 遇到回车
  129. if(*string=='n')
  130. {
  131. y+=fHeight*fScale;
  132. fx=x;
  133. }
  134. // 遇到汉字
  135. else if(hz0 >= HZ_HIGH_FIX && hz0 <= HZ_HIGH_END)
  136. {
  137. letters[hz0 - HZ_HIGH_FIX][hz1 - HZ_LOW_FIX]->RenderEx(fx, y, fRot, fScale);
  138. fx+=(letters[hz0 - HZ_HIGH_FIX][hz1 - HZ_LOW_FIX]->GetWidth()+fTracking)*fScale;
  139. string++;
  140. }
  141. // 遇到英文
  142. else if(hz0 >= ASCII_FIX && hz0 < ASCII_END)
  143. {
  144. letters[HZ_HIGH_MAX - VALUE_FIX][hz0 - ASCII_FIX]->RenderEx(fx, y, fRot, fScale);
  145. fx+=(letters[HZ_HIGH_MAX - VALUE_FIX][hz0 - ASCII_FIX]->GetWidth()+fTracking)*fScale;
  146. }
  147. else
  148. {
  149. letters[HZ_HIGH_MAX - VALUE_FIX]['?']->RenderEx(fx, y, fRot, fScale);
  150. fx+=(letters[HZ_HIGH_MAX - VALUE_FIX]['?']->GetWidth()+fTracking)*fScale;
  151. }
  152. string++;
  153. }
  154. }
  155. //绘制格式字符串
  156. void hgeFontCN::printf(float x, float y, const char *format, ...)
  157. {
  158. char buffer[1024];
  159. char *pArg=(char *) &format+sizeof(format);
  160. vsprintf(buffer, format, pArg);
  161. Render(x,y,buffer);
  162. }
  163. //设置字体颜色
  164. void hgeFontCN::SetColor(DWORD col)
  165. {
  166. dwCol=col;
  167. for(int i=0;i<HZ_HIGH_MAX;i++)
  168. {
  169. for(int j=0;j<HZ_LOW_MAX;j++)
  170. {
  171. if(letters[i][j])
  172. letters[i][j]->SetColor(col);
  173. }
  174. }
  175. }
  176. //设置Z缓冲
  177. void hgeFontCN::SetZ(float z)
  178. {
  179. fZ=z;
  180. for(int i=0;i<HZ_HIGH_MAX;i++)
  181. {
  182. for(int j=0;j<HZ_LOW_MAX;j++)
  183. {
  184. if(letters[i][j])
  185. letters[i][j]->SetZ(z);
  186. }
  187. }
  188. }
  189. //设置混和模式
  190. void hgeFontCN::SetBlendMode(int blend)
  191. {
  192. nBlend=blend;
  193. for(int i=0;i<HZ_HIGH_MAX;i++)
  194. {
  195. for(int j=0;j<HZ_LOW_MAX;j++)
  196. {
  197. if(letters[i][j])
  198. letters[i][j]->SetBlendMode(blend);
  199. }
  200. }
  201. }
  202. //获得字符串的宽度(汉字按两个字节、字母按照一个字节算)
  203. float hgeFontCN::GetStringWidth(const char *string) const
  204. {
  205. float w = 0;
  206. while(*string && *string!='n')
  207. {
  208. BYTE hz0 = (unsigned char)*string;
  209. BYTE hz1 = (unsigned char)*(string+1);
  210. // 遇到汉字
  211. if(hz0 >= HZ_HIGH_FIX && hz0 <= HZ_HIGH_END)
  212. {
  213. w += letters[hz0 - HZ_HIGH_FIX][hz1 - HZ_LOW_FIX]->GetWidth() + fTracking;
  214. string++;
  215. }
  216. // 遇到英文
  217. else if(hz0 >= ASCII_FIX && hz0 < ASCII_END)
  218. {
  219. w += letters[HZ_HIGH_MAX - VALUE_FIX][hz0 - ASCII_FIX]->GetWidth() + fTracking;
  220. }
  221. else
  222. {
  223. w += letters[HZ_HIGH_MAX - VALUE_FIX]['?']->GetWidth() + fTracking;
  224. }
  225. string++;
  226. }
  227. return w * fScale;
  228. }
  229. //获得指定的精灵
  230. hgeSprite* hgeFontCN::GetSprite(BYTE chH,BYTE chL) const
  231. {
  232. if (chH < HZ_HIGH_MAX && chL < HZ_LOW_MAX)
  233. return letters[chH][chL];
  234. return NULL;
  235. }