PageRenderTime 55ms CodeModel.GetById 26ms RepoModel.GetById 1ms app.codeStats 0ms

/branches/IsengardDev/IronHells/src/client/sdl/bfont.c

#
C | 724 lines | 454 code | 146 blank | 124 comment | 60 complexity | 6baf2b5b3329bb162ad59274ef4cccbf MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, Apache-2.0
  1. /************************************************************/
  2. /* */
  3. /* BFONT.c v. 1.0.4-1 - Billi Font Library by Diego Billi */
  4. /* */
  5. /* mail: dbilli@cs.unibo.it */
  6. /* home: http://www.cs.unibo.it/~dbilli (ITALIAN) */
  7. /* */
  8. /************************************************************/
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <stdarg.h>
  13. #include "SDL_image.h"
  14. #include "angband.h"
  15. #include "sdl/bfont.h"
  16. // ATTENTION: MS Visual C++ do not declarate vsnprintf in <stdio.h>
  17. #ifdef WIN32
  18. #define vsnprintf _vsnprintf
  19. #endif
  20. /* Current font */
  21. static BFont_Info *CurrentFont;
  22. /* buffer size for buffered prints*/
  23. #define BFONT_BUFFER_LEN 1024
  24. /* Single global var for buffered prints */
  25. static char bfont_buffer[BFONT_BUFFER_LEN];
  26. /* utility functions */
  27. static Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y);
  28. static void PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel);
  29. int InitFont(BFont_Info *Font)
  30. {
  31. int x = 0, i = 0;
  32. Uint32 sentry;
  33. i = '!';
  34. sentry = GetPixel(Font->Surface,0,0);
  35. /* sentry = SDL_MapRGB(Font->Surface->format, 255, 0, 255); */
  36. if ( Font->Surface==NULL ) {
  37. fprintf(stderr,"BFont: The font has not been loaded!\n");
  38. return 1;
  39. }
  40. if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
  41. x=0;
  42. while ( x < (Font->Surface->w-1) ) {
  43. if(GetPixel(Font->Surface,x,0) != sentry) {
  44. Font->Chars[i].x = x;
  45. Font->Chars[i].y = 1;
  46. Font->Chars[i].h = Font->Surface->h;
  47. for (; GetPixel(Font->Surface, x, 0) != sentry && x < (Font->Surface->w); ++x) ;
  48. Font->Chars[i].w = (x - Font->Chars[i].x);
  49. i++;
  50. }
  51. else {
  52. x++;
  53. }
  54. }
  55. Font->Chars[' '].x = 0;
  56. Font->Chars[' '].y = 0;
  57. Font->Chars[' '].h = Font->Surface->h;
  58. Font->Chars[' '].w = Font->Chars['!'].w;
  59. if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
  60. Font->h = Font->Surface->h;
  61. SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1));
  62. return 0;
  63. }
  64. /* Load the font and stores it in the BFont_Info structure */
  65. BFont_Info * LoadFont (const char *filename)
  66. {
  67. SDL_Surface *surface = NULL;
  68. int x;
  69. BFont_Info *Font=NULL;
  70. if (filename != NULL) {
  71. Font = (BFont_Info *) malloc(sizeof(BFont_Info));
  72. if (Font != NULL) {
  73. surface = (SDL_Surface *) IMG_Load(filename);
  74. if (surface != NULL) {
  75. Font->Surface = surface;
  76. for (x=0; x<256; x++) {
  77. Font->Chars[x].x = 0;
  78. Font->Chars[x].y = 0;
  79. Font->Chars[x].h = 0;
  80. Font->Chars[x].w = 0;
  81. }
  82. /* Init the font */
  83. InitFont(Font);
  84. /* Set the font as the current font */
  85. SetCurrentFont(Font);
  86. }
  87. else {
  88. /* free memory allocated for the BFont_Info structure */
  89. free(Font);
  90. Font = NULL;
  91. }
  92. }
  93. }
  94. return Font;
  95. }
  96. BFont_Info * LoadFontFromSurface (SDL_Surface *Surface)
  97. {
  98. int x;
  99. BFont_Info *Font=NULL;
  100. if (Surface != NULL) {
  101. Font = (BFont_Info *) malloc(sizeof(BFont_Info));
  102. if (Font != NULL) {
  103. Font->Surface = Surface;
  104. for (x=0; x<256; x++) {
  105. Font->Chars[x].x = 0;
  106. Font->Chars[x].y = 0;
  107. Font->Chars[x].h = 0;
  108. Font->Chars[x].w = 0;
  109. }
  110. /* Init the font */
  111. InitFont(Font);
  112. /* Set the font as the current font */
  113. SetCurrentFont(Font);
  114. }
  115. }
  116. return Font;
  117. }
  118. void FreeFont(BFont_Info *Font)
  119. {
  120. fprintf(stderr, "FreeFont()\n");
  121. if(!Font)
  122. return;
  123. fprintf(stderr, "Freeing font surface.\n");
  124. if(Font->Surface)
  125. SDL_FreeSurface(Font->Surface);
  126. fprintf(stderr, "Freeing font structure.\n");
  127. free(Font);
  128. }
  129. BFont_Info * SetFontColor(BFont_Info *Font,Uint8 r, Uint8 g, Uint8 b)
  130. {
  131. int x,y;
  132. BFont_Info *newfont;
  133. SDL_Surface *surface = NULL;
  134. Uint32 pixel;
  135. Uint8 old_r, old_g, old_b;
  136. Uint8 new_r, new_g, new_b;
  137. Uint32 color_key;
  138. newfont = (BFont_Info *) malloc(sizeof(BFont_Info));
  139. memset(newfont, 0, sizeof(BFont_Info));
  140. if (newfont != NULL) {
  141. newfont->h = Font->h;
  142. for (x=0; x<256; x++) {
  143. newfont->Chars[x].x = Font->Chars[x].x;
  144. newfont->Chars[x].y = Font->Chars[x].y;
  145. newfont->Chars[x].h = Font->Chars[x].h;
  146. newfont->Chars[x].w = Font->Chars[x].w;
  147. }
  148. surface = SDL_ConvertSurface(Font->Surface, Font->Surface->format, Font->Surface->flags);
  149. if (surface != NULL) {
  150. if (SDL_MUSTLOCK(surface)) SDL_LockSurface(surface);
  151. if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
  152. color_key = GetPixel(surface, 0, surface->h-1);
  153. printf("looking...\n");
  154. for( x=0; x < Font->Surface->w; x++) {
  155. for( y=0; y < Font->Surface->h; y++) {
  156. old_r = old_g = old_b = 0;
  157. pixel = GetPixel(Font->Surface,x,y);
  158. if (pixel != color_key) {
  159. SDL_GetRGB(pixel, surface->format, &old_r,&old_g,&old_b);
  160. new_r = (Uint8) ((old_r * r) / 255);
  161. new_g = (Uint8) ((old_g * g) / 255);
  162. new_b = (Uint8) ((old_b * b) / 255);
  163. pixel = SDL_MapRGB(surface->format,new_r,new_g,new_b);
  164. PutPixel(surface,x,y,pixel);
  165. }
  166. }
  167. }
  168. printf("unlooking...\n");
  169. if (SDL_MUSTLOCK(surface)) SDL_UnlockSurface(surface);
  170. if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
  171. SDL_SetColorKey(surface, SDL_SRCCOLORKEY, color_key);
  172. }
  173. newfont->Surface = surface;
  174. }
  175. return newfont;
  176. }
  177. /* Set the current font */
  178. void SetCurrentFont(BFont_Info *Font)
  179. {
  180. CurrentFont = Font;
  181. }
  182. /* Returns the pointer to the current font strucure in use */
  183. BFont_Info * GetCurrentFont(void)
  184. {
  185. return CurrentFont;
  186. }
  187. /* Return the font height */
  188. int FontHeight (BFont_Info *Font)
  189. {
  190. return (Font->h);
  191. }
  192. void SetFontHeight(BFont_Info *Font, int height)
  193. {
  194. Font->h = height;
  195. }
  196. /* Return the width of the "c" character */
  197. int CharWidth(BFont_Info *Font,int c)
  198. {
  199. return Font->Chars[c].w;
  200. }
  201. /* Puts a single char on the surface */
  202. int PutChar(SDL_Surface *Surface, int x, int y, int c)
  203. {
  204. return PutCharFont(Surface, CurrentFont, x,y,c);
  205. }
  206. /* Puts a single char on the surface with the specified font */
  207. int PutCharFont(SDL_Surface *Surface, BFont_Info *Font,int x, int y, int c)
  208. {
  209. int r=0;
  210. SDL_Rect dest;
  211. dest.w = CharWidth(Font,' ');
  212. dest.h = FontHeight(Font);
  213. dest.x = x;
  214. dest.y = y;
  215. if (c != ' ') {
  216. SDL_BlitSurface( Font->Surface, &Font->Chars[c], Surface, &dest);
  217. }
  218. r = dest.w;
  219. return r;
  220. }
  221. void PutString(SDL_Surface *Surface, int x, int y, const char *text)
  222. {
  223. PutStringFont(Surface, CurrentFont, x, y, text);
  224. }
  225. void PutStringFont(SDL_Surface *Surface, BFont_Info *Font, int x, int y, const char *text)
  226. {
  227. int i=0;
  228. while (text[i]!='\0') {
  229. x += PutCharFont(Surface,Font,x,y,text[i]);
  230. i++;
  231. }
  232. }
  233. int TextWidth(const char *text)
  234. {
  235. return TextWidthFont( CurrentFont, text);
  236. }
  237. int TextWidthFont(BFont_Info *Font, const char *text)
  238. {
  239. int i=0,x=0;
  240. while (text[i]!='\0') {
  241. x += CharWidth(Font,text[i]);
  242. i++;
  243. }
  244. return x;
  245. }
  246. /* counts the spaces of the strings */
  247. static int count (const char *text)
  248. {
  249. char *p = NULL;
  250. int pos = -1;
  251. int i = 0;
  252. /* Calculate the space occupied by the text without spaces */
  253. while ((p=strchr(&text[pos+1],' ')) != NULL) {
  254. i++;
  255. pos = p - text;
  256. }
  257. return i;
  258. }
  259. void JustifiedPutString(SDL_Surface *Surface, int y, const char *text)
  260. {
  261. JustifiedPutStringFont( Surface, CurrentFont, y,text);
  262. }
  263. void JustifiedPutStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *text)
  264. {
  265. int spaces = 0;
  266. int gap;
  267. int single_gap;
  268. int dif;
  269. char *strtmp;
  270. char *p;
  271. int pos = -1;
  272. int xpos = 0;
  273. if (strchr(text,' ') == NULL) {
  274. PutStringFont(Surface, Font, 0, y, text);
  275. }
  276. else {
  277. gap = (Surface->w-1) - TextWidthFont(Font,text);
  278. if (gap <= 0) {
  279. PutStringFont(Surface, Font,0,y,text);
  280. } else {
  281. spaces = count(text);
  282. dif = gap % spaces;
  283. single_gap = (gap - dif) / spaces;
  284. xpos=0;
  285. pos = -1;
  286. while ( spaces > 0 ) {
  287. p = strstr(&text[pos+1]," ");
  288. strtmp = NULL;
  289. strtmp = (char *) calloc ( (p - &text[pos+1]) + 1,sizeof(char));
  290. if (strtmp != NULL) {
  291. strncpy (strtmp, &text[pos+1], (p - &text[pos+1]));
  292. PutStringFont(Surface, Font, xpos, y, strtmp);
  293. xpos = xpos + TextWidthFont(Font, strtmp) + single_gap + CharWidth(Font,' ');
  294. if (dif >= 0) {
  295. xpos ++;
  296. dif--;
  297. }
  298. pos = p - text;
  299. spaces--;
  300. free(strtmp);
  301. }
  302. }
  303. strtmp = NULL;
  304. strtmp = (char *) calloc ( strlen( &text[pos+1]) + 1,sizeof(char));
  305. if (strtmp != NULL) {
  306. strncpy (strtmp, &text[pos+1], strlen( &text[pos+1]));
  307. PutStringFont(Surface, Font,xpos, y, strtmp);
  308. free(strtmp);
  309. }
  310. }
  311. }
  312. }
  313. void CenteredPutString(SDL_Surface *Surface, int y, const char *text)
  314. {
  315. CenteredPutStringFont(Surface, CurrentFont, y, text);
  316. }
  317. void CenteredPutStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *text)
  318. {
  319. PutStringFont(Surface, Font, Surface->w/2-TextWidthFont(Font,text)/2, y, text);
  320. }
  321. void RightPutString(SDL_Surface *Surface, int y, const char *text)
  322. {
  323. RightPutStringFont(Surface, CurrentFont, y, text);
  324. }
  325. void RightPutStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *text)
  326. {
  327. PutStringFont(Surface, Font, Surface->w - TextWidthFont(Font,text) - 1, y, text);
  328. }
  329. void LeftPutString(SDL_Surface *Surface, int y, const char *text)
  330. {
  331. LeftPutStringFont(Surface, CurrentFont, y, text);
  332. }
  333. void LeftPutStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *text)
  334. {
  335. PutStringFont(Surface, Font, 0, y, text);
  336. }
  337. /******/
  338. void PrintString (SDL_Surface *Surface, int x, int y, const char *fmt, ...)
  339. {
  340. va_list args;
  341. va_start (args,fmt);
  342. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  343. va_end(args);
  344. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  345. PutStringFont(Surface, CurrentFont, x, y, bfont_buffer);
  346. // va_list args;
  347. // char *temp;
  348. // va_start (args,fmt);
  349. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  350. // vsprintf(temp,fmt,args);
  351. // PutStringFont(Surface, CurrentFont, x, y, temp);
  352. // free (temp);
  353. // }
  354. // va_end(args);
  355. }
  356. void PrintStringFont(SDL_Surface *Surface, BFont_Info *Font, int x, int y, const char *fmt, ...)
  357. {
  358. va_list args;
  359. va_start (args,fmt);
  360. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  361. va_end(args);
  362. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  363. PutStringFont(Surface, Font, x, y, bfont_buffer);
  364. // va_list args;
  365. // char *temp;
  366. // va_start (args,fmt);
  367. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  368. // vsprintf(temp,fmt,args);
  369. // PutStringFont(Surface, Font, x, y, temp);
  370. // free (temp);
  371. // }
  372. // va_end(args);
  373. }
  374. void CenteredPrintString(SDL_Surface *Surface, int y, const char *fmt, ...)
  375. {
  376. va_list args;
  377. va_start (args,fmt);
  378. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  379. va_end(args);
  380. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  381. CenteredPutString(Surface, y, bfont_buffer);
  382. // va_list args;
  383. // char *temp;
  384. // va_start (args,fmt);
  385. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  386. // vsprintf(temp,fmt,args);
  387. // CenteredPutString(Surface, y, temp);
  388. // free (temp);
  389. // }
  390. // va_end(args);
  391. }
  392. void CenteredPrintStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *fmt, ...)
  393. {
  394. va_list args;
  395. va_start (args,fmt);
  396. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  397. va_end(args);
  398. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  399. CenteredPutStringFont(Surface, Font, y, bfont_buffer);
  400. // va_list args;
  401. // char *temp;
  402. // va_start (args,fmt);
  403. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  404. // vsprintf(temp,fmt,args);
  405. // CenteredPutStringFont(Surface, Font, y, temp);
  406. // free (temp);
  407. // }
  408. // va_end(args);
  409. }
  410. void RightPrintString(SDL_Surface *Surface, int y, const char *fmt, ...)
  411. {
  412. va_list args;
  413. va_start (args,fmt);
  414. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  415. va_end(args);
  416. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  417. RightPutString(Surface, y, bfont_buffer);
  418. // va_list args;
  419. // char *temp;
  420. // va_start (args,fmt);
  421. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  422. // vsprintf(temp,fmt,args);
  423. // RightPutString(Surface, y, temp);
  424. // free (temp);
  425. // }
  426. // va_end(args);
  427. }
  428. void RightPrintStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *fmt, ...)
  429. {
  430. va_list args;
  431. va_start (args,fmt);
  432. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  433. va_end(args);
  434. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  435. RightPutStringFont(Surface, Font, y, bfont_buffer);
  436. // va_list args;
  437. // char *temp;
  438. // va_start (args,fmt);
  439. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  440. // vsprintf(temp,fmt,args);
  441. // RightPutStringFont(Surface, Font, y, temp);
  442. // free (temp);
  443. // }
  444. // va_end(args);
  445. }
  446. void LeftPrintString(SDL_Surface *Surface, int y, const char *fmt, ...)
  447. {
  448. va_list args;
  449. va_start (args,fmt);
  450. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  451. va_end(args);
  452. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  453. LeftPutString(Surface, y, bfont_buffer);
  454. // va_list args;
  455. // char *temp;
  456. // va_start (args,fmt);
  457. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  458. // vsprintf(temp,fmt,args);
  459. // LeftPutString(Surface, y, temp);
  460. // free (temp);
  461. // }
  462. // va_end(args);
  463. }
  464. void LeftPrintStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *fmt, ...)
  465. {
  466. va_list args;
  467. va_start (args,fmt);
  468. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  469. va_end(args);
  470. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  471. LeftPutStringFont(Surface, Font, y, bfont_buffer);
  472. // va_list args;
  473. // char *temp;
  474. // va_start (args,fmt);
  475. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  476. // vsprintf(temp,fmt,args);
  477. // LeftPutStringFont(Surface, Font, y, temp);
  478. // free (temp);
  479. // }
  480. // va_end(args);
  481. }
  482. void JustifiedPrintString(SDL_Surface *Surface, int y, const char *fmt, ...)
  483. {
  484. va_list args;
  485. va_start (args,fmt);
  486. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  487. va_end(args);
  488. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  489. JustifiedPutString( Surface, y,bfont_buffer);
  490. // va_list args;
  491. // char *temp;
  492. // va_start (args,fmt);
  493. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  494. // vsprintf(temp,fmt,args);
  495. // JustifiedPutString( Surface, y,temp);
  496. // free (temp);
  497. // }
  498. // va_end(args);
  499. }
  500. void JustifiedPrintStringFont(SDL_Surface *Surface, BFont_Info *Font, int y, const char *fmt, ...)
  501. {
  502. va_list args;
  503. va_start (args,fmt);
  504. vsnprintf(bfont_buffer,BFONT_BUFFER_LEN,fmt,args);
  505. va_end(args);
  506. bfont_buffer[BFONT_BUFFER_LEN-1] = '\0';
  507. JustifiedPutStringFont( Surface, Font, y,bfont_buffer);
  508. // va_list args;
  509. // char *temp;
  510. // va_start (args,fmt);
  511. // if ( (temp = (char *) malloc(1000+1)) != NULL) {
  512. // vsprintf(temp,fmt,args);
  513. // JustifiedPutStringFont( Surface, Font, y,temp);
  514. // free (temp);
  515. // }
  516. // va_end(args);
  517. }
  518. /*********************************************************************************************************/
  519. /*********************************************************************************************************/
  520. /*********************************************************************************************************/
  521. void PutPixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
  522. {
  523. int bpp = surface->format->BytesPerPixel;
  524. /* Here p is the address to the pixel we want to set */
  525. Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
  526. switch(bpp) {
  527. case 1:
  528. *p = pixel;
  529. break;
  530. case 2:
  531. *(Uint16 *)p = pixel;
  532. break;
  533. case 3:
  534. if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
  535. p[0] = (pixel >> 16) & 0xff;
  536. p[1] = (pixel >> 8) & 0xff;
  537. p[2] = pixel & 0xff;
  538. } else {
  539. p[0] = pixel & 0xff;
  540. p[1] = (pixel >> 8) & 0xff;
  541. p[2] = (pixel >> 16) & 0xff;
  542. }
  543. break;
  544. case 4:
  545. *(Uint32 *)p = pixel;
  546. break;
  547. }
  548. }
  549. Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
  550. {
  551. Uint8 *bits;
  552. Uint32 Bpp;
  553. if (X<0) puts("x too small in GetPixel!");
  554. if (X>=Surface->w) puts("x too big in GetPixel!");
  555. Bpp = Surface->format->BytesPerPixel;
  556. bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
  557. // Get the pixel
  558. switch(Bpp) {
  559. case 1:
  560. return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
  561. break;
  562. case 2:
  563. return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
  564. break;
  565. case 3: { // Format/endian independent
  566. Uint8 r, g, b;
  567. r = *((bits)+Surface->format->Rshift/8);
  568. g = *((bits)+Surface->format->Gshift/8);
  569. b = *((bits)+Surface->format->Bshift/8);
  570. return SDL_MapRGB(Surface->format, r, g, b);
  571. }
  572. break;
  573. case 4:
  574. return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
  575. break;
  576. }
  577. return -1;
  578. }