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

游戏引擎

开发平台:

Visual C++

  1. /*
  2. ** Haaf's Game Engine 1.5
  3. ** Copyright (C) 2003-2004, Relish Games
  4. ** hge.relishgames.com
  5. **
  6. ** hgeFont helper class implementation
  7. */
  8. #include "....includehgefont.h"
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. const char FNTHEADERTAG[]="[HGEFONT]";
  12. const char FNTBITMAPTAG[]="Bitmap";
  13. const char FNTCHARTAG[]="Char";
  14. HGE *hgeFont::hge=0;
  15. hgeFont::hgeFont(const char *szFont)
  16. {
  17. void *data;
  18. DWORD size;
  19. char *desc, *pdesc;
  20. char linebuf[256];
  21. char buf[MAX_PATH], *pbuf;
  22. char chr;
  23. int i, x, y, w, h, a, c;
  24. // Setup variables
  25. hge=hgeCreate(HGE_VERSION);
  26. fHeight=0.0f;
  27. fScale=1.0f;
  28. fRot=0.0f;
  29. fTracking=0.0f;
  30. fSpacing=1.0f;
  31. hTexture=0;
  32. fZ=0.5f;
  33. nBlend=BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE;
  34. dwCol=0xFFFFFFFF;
  35. ZeroMemory( &letters, sizeof(letters) );
  36. ZeroMemory( &pre, sizeof(letters) );
  37. ZeroMemory( &post, sizeof(letters) );
  38. // Load font description
  39. data=hge->Resource_Load(szFont, &size);
  40. if(!data) return;
  41. desc = new char[size+1];
  42. memcpy(desc,data,size);
  43. desc[size]=0;
  44. hge->Resource_Free(data);
  45. pdesc=_get_line(desc,linebuf);
  46. if(strcmp(linebuf, FNTHEADERTAG))
  47. {
  48. hge->System_Log("Font %s has incorrect format.", szFont);
  49. delete[] desc;
  50. return;
  51. }
  52. // Parse font description
  53. while((pdesc=_get_line(pdesc,linebuf)))
  54. {
  55. if(!strncmp(linebuf, FNTBITMAPTAG, sizeof(FNTBITMAPTAG)-1 ))
  56. {
  57. strcpy(buf,szFont);
  58. pbuf=strrchr(buf,'\');
  59. if(!pbuf) pbuf=strrchr(buf,'/');
  60. if(!pbuf) pbuf=buf;
  61. else pbuf++;
  62. if(!sscanf(linebuf, "Bitmap = %s", pbuf)) continue;
  63. hTexture=hge->Texture_Load(buf);
  64. if(!hTexture)
  65. {
  66. delete[] desc;
  67. return;
  68. }
  69. }
  70. else if(!strncmp(linebuf, FNTCHARTAG, sizeof(FNTCHARTAG)-1 ))
  71. {
  72. pbuf=strchr(linebuf,'=');
  73. if(!pbuf) continue;
  74. pbuf++;
  75. while(*pbuf==' ') pbuf++;
  76. if(*pbuf=='"')
  77. {
  78. pbuf++;
  79. i=(unsigned char)*pbuf++;
  80. pbuf++; // skip "
  81. }
  82. else
  83. {
  84. i=0;
  85. while((*pbuf>='0' && *pbuf<='9') || (*pbuf>='A' && *pbuf<='F') || (*pbuf>='a' && *pbuf<='f'))
  86. {
  87. chr=*pbuf;
  88. if(chr >= 'a') chr-='a'-':';
  89. if(chr >= 'A') chr-='A'-':';
  90. chr-='0';
  91. if(chr>0xF) chr=0xF;
  92. i=(i << 4) | chr;
  93. pbuf++;
  94. }
  95. if(i<0 || i>255) continue;
  96. }
  97. sscanf(pbuf, " , %d , %d , %d , %d , %d , %d", &x, &y, &w, &h, &a, &c);
  98. letters[i] = new hgeSprite(hTexture, (float)x, (float)y, (float)w, (float)h);
  99. pre[i]=(float)a;
  100. post[i]=(float)c;
  101. if(h>fHeight) fHeight=(float)h;
  102. }
  103. }
  104. delete[] desc;
  105. }
  106. hgeFont::hgeFont(const hgeFont &fnt)
  107. {
  108. int i;
  109. hge=hgeCreate(HGE_VERSION);
  110. hTexture=fnt.hTexture;
  111. fHeight=fnt.fHeight;
  112. fScale=fnt.fScale;
  113. fRot=fnt.fRot;
  114. fTracking=fnt.fTracking;
  115. fSpacing=fnt.fSpacing;
  116. dwCol=fnt.dwCol;
  117. fZ=fnt.fZ;
  118. nBlend=fnt.nBlend;
  119. for(i=0; i<256; i++)
  120. {
  121. if(fnt.letters[i]) letters[i]=new hgeSprite(*fnt.letters[i]);
  122. else letters[i]=0;
  123. pre[i]=fnt.pre[i];
  124. post[i]=fnt.post[i];
  125. }
  126. }
  127. hgeFont& hgeFont::operator= (const hgeFont &fnt)
  128. {
  129. int i;
  130. if(this!=&fnt)
  131. {
  132. hTexture=fnt.hTexture;
  133. fHeight=fnt.fHeight;
  134. fScale=fnt.fScale;
  135. fRot=fnt.fRot;
  136. fTracking=fnt.fTracking;
  137. fSpacing=fnt.fSpacing;
  138. dwCol=fnt.dwCol;
  139. fZ=fnt.fZ;
  140. nBlend=fnt.nBlend;
  141. for(i=0; i<256; i++)
  142. {
  143. if(letters[i]) delete letters[i];
  144. if(fnt.letters[i]) letters[i]=new hgeSprite(*fnt.letters[i]);
  145. else letters[i]=0;
  146. pre[i]=fnt.pre[i];
  147. post[i]=fnt.post[i];
  148. }
  149. }
  150. return *this;
  151. }
  152. hgeFont::~hgeFont()
  153. {
  154. for(int i=0; i<256; i++)
  155. if(letters[i]) delete letters[i];
  156. if(hTexture) hge->Texture_Free(hTexture);
  157. hge->Release();
  158. }
  159. void hgeFont::Render(float x, float y, int align, const char *string)
  160. {
  161. int i;
  162. float fx=x;
  163. align &= HGETEXT_HORZMASK;
  164. if(align==HGETEXT_RIGHT) fx-=GetStringWidth(string);
  165. if(align==HGETEXT_CENTER) fx-=int(GetStringWidth(string)/2.0f);
  166. while(*string)
  167. {
  168. if(*string=='n')
  169. {
  170. y+=int(fHeight*fScale*fSpacing);
  171. fx=x;
  172. if(align==HGETEXT_RIGHT) fx-=GetStringWidth(string+1);
  173. if(align==HGETEXT_CENTER) fx-=int(GetStringWidth(string+1)/2.0f);
  174. }
  175. else
  176. {
  177. i=(unsigned char)*string;
  178. if(!letters[i]) i='?';
  179. if(letters[i])
  180. {
  181. fx+=pre[i]*fScale;
  182. letters[i]->RenderEx(fx, y, fRot, fScale);
  183. fx+=(letters[i]->GetWidth()+post[i]+fTracking)*fScale;
  184. }
  185. }
  186. string++;
  187. }
  188. }
  189. void hgeFont::printf(float x, float y, int align, const char *format, ...)
  190. {
  191. char *pArg=(char *) &format+sizeof(format);
  192. vsprintf(buffer, format, pArg);
  193. Render(x,y,align,buffer);
  194. }
  195. void hgeFont::printfb(float x, float y, float w, float h, int align, const char *format, ...)
  196. {
  197. char chr, *pbuf, *prevword, *linestart;
  198. int i,lines=0;
  199. float tx, ty, hh, ww;
  200. char *pArg=(char *) &format+sizeof(format);
  201. vsprintf(buffer, format, pArg);
  202. linestart=buffer;
  203. pbuf=buffer;
  204. prevword=0;
  205. for(;;)
  206. {
  207. i=0;
  208. while(pbuf[i] && pbuf[i]!=' ' && pbuf[i]!='n') i++;
  209. chr=pbuf[i];
  210. pbuf[i]=0;
  211. ww=GetStringWidth(linestart);
  212. pbuf[i]=chr;
  213. if(ww > w)
  214. {
  215. if(pbuf==linestart)
  216. {
  217. pbuf[i]='n';
  218. linestart=&pbuf[i+1];
  219. }
  220. else
  221. {
  222. *prevword='n';
  223. linestart=prevword+1;
  224. }
  225. lines++;
  226. }
  227. if(pbuf[i]=='n')
  228. {
  229. prevword=&pbuf[i];
  230. linestart=&pbuf[i+1];
  231. pbuf=&pbuf[i+1];
  232. lines++;
  233. continue;
  234. }
  235. if(!pbuf[i]) {lines++;break;}
  236. prevword=&pbuf[i];
  237. pbuf=&pbuf[i+1];
  238. }
  239. tx=x;
  240. ty=y;
  241. hh=fHeight*fSpacing*fScale*lines;
  242. switch(align & HGETEXT_HORZMASK)
  243. {
  244. case HGETEXT_LEFT: break;
  245. case HGETEXT_RIGHT: tx+=w; break;
  246. case HGETEXT_CENTER: tx+=int(w/2); break;
  247. }
  248. switch(align & HGETEXT_VERTMASK)
  249. {
  250. case HGETEXT_TOP: break;
  251. case HGETEXT_BOTTOM: ty+=h-hh; break;
  252. case HGETEXT_MIDDLE: ty+=int((h-hh)/2); break;
  253. }
  254. Render(tx,ty,align,buffer);
  255. }
  256. float hgeFont::GetStringWidth(const char *string) const
  257. {
  258. int i;
  259. float w=0;
  260. while(*string && *string!='n')
  261. {
  262. i=(unsigned char)*string;
  263. if(!letters[i]) i='?';
  264. if(letters[i]) w+=letters[i]->GetWidth()+pre[i]+post[i]+fTracking;
  265. string++;
  266. }
  267. return w*fScale;
  268. }
  269. void hgeFont::SetColor(DWORD col)
  270. {
  271. dwCol=col;
  272. for(int i=0;i<256;i++) if(letters[i]) letters[i]->SetColor(col);
  273. }
  274. void hgeFont::SetZ(float z)
  275. {
  276. fZ=z;
  277. for(int i=0;i<256;i++) if(letters[i]) letters[i]->SetZ(z);
  278. }
  279. void hgeFont::SetBlendMode(int blend)
  280. {
  281. nBlend=blend;
  282. for(int i=0;i<256;i++) if(letters[i]) letters[i]->SetBlendMode(blend);
  283. }
  284. char *hgeFont::_get_line(char *file, char *line)
  285. {
  286. int i=0;
  287. while(file[i] && file[i]!='n' && file[i]!='r')
  288. {
  289. line[i]=file[i];
  290. i++;
  291. }
  292. line[i]=0;
  293. while(file[i] && (file[i]=='n' || file[i]=='r')) i++;
  294. if(file[i]) return file+i;
  295. else return 0;
  296. }