hgefont.cpp
上传用户:jnfxsk
上传日期:2022-06-16
资源大小:3675k
文件大小:6k
源码类别:

游戏引擎

开发平台:

Visual C++

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