PageRenderTime 38ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/barrage-1.0.4/src/SFont.c

#
C | 226 lines | 184 code | 28 blank | 14 comment | 26 complexity | 5c933bfaa1c7d1dd0ed2501e077cb14d MD5 | raw file
Possible License(s): GPL-2.0
  1. #include "SDL.h"
  2. #include "SFont.h"
  3. #include <string.h>
  4. #include <stdlib.h>
  5. SFont_FontInfo InternalFont;
  6. Uint32 GetPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
  7. {
  8. Uint8 *bits;
  9. Uint32 Bpp;
  10. if (X<0) puts("SFONT ERROR: x too small in GetPixel. Report this to <karlb@gmx.net>");
  11. if (X>=Surface->w) puts("SFONT ERROR: x too big in GetPixel. Report this to <karlb@gmx.net>");
  12. Bpp = Surface->format->BytesPerPixel;
  13. bits = ((Uint8 *)Surface->pixels)+Y*Surface->pitch+X*Bpp;
  14. // Get the pixel
  15. switch(Bpp) {
  16. case 1:
  17. return *((Uint8 *)Surface->pixels + Y * Surface->pitch + X);
  18. break;
  19. case 2:
  20. return *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X);
  21. break;
  22. case 3: { // Format/endian independent
  23. Uint8 r, g, b;
  24. r = *((bits)+Surface->format->Rshift/8);
  25. g = *((bits)+Surface->format->Gshift/8);
  26. b = *((bits)+Surface->format->Bshift/8);
  27. return SDL_MapRGB(Surface->format, r, g, b);
  28. }
  29. break;
  30. case 4:
  31. return *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X);
  32. break;
  33. }
  34. return -1;
  35. }
  36. void InitFont2(SFont_FontInfo *Font)
  37. {
  38. int x = 0, i = 0;
  39. if ( Font->Surface==NULL ) {
  40. printf("The font has not been loaded!\n");
  41. exit(1);
  42. }
  43. if (SDL_MUSTLOCK(Font->Surface)) SDL_LockSurface(Font->Surface);
  44. while ( x < Font->Surface->w ) {
  45. if(GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)) {
  46. Font->CharPos[i++]=x;
  47. while (( x < Font->Surface->w-1) && (GetPixel(Font->Surface,x,0)==SDL_MapRGB(Font->Surface->format,255,0,255)))
  48. x++;
  49. Font->CharPos[i++]=x;
  50. }
  51. x++;
  52. }
  53. if (SDL_MUSTLOCK(Font->Surface)) SDL_UnlockSurface(Font->Surface);
  54. Font->h=Font->Surface->h;
  55. SDL_SetColorKey(Font->Surface, SDL_SRCCOLORKEY, GetPixel(Font->Surface, 0, Font->Surface->h-1));
  56. }
  57. void InitFont(SDL_Surface *Font)
  58. {
  59. InternalFont.Surface=Font;
  60. InitFont2(&InternalFont);
  61. }
  62. void PutString2(SDL_Surface *Surface, SFont_FontInfo *Font, int x, int y, char *text)
  63. {
  64. int ofs;
  65. int i=0;
  66. SDL_Rect srcrect,dstrect;
  67. while (text[i]!='\0') {
  68. if (text[i]==' ') {
  69. x+=Font->CharPos[2]-Font->CharPos[1];
  70. i++;
  71. }
  72. else {
  73. // printf("-%c- %c - %u\n",228,text[i],text[i]);
  74. ofs=((unsigned char)text[i]-33)*2+1;
  75. // ofs=(text[i]-33)*2+1;
  76. // printf("printing %c %d\n",text[i],ofs);
  77. srcrect.w = dstrect.w = (Font->CharPos[ofs+2]+Font->CharPos[ofs+1])/2-(Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
  78. srcrect.h = dstrect.h = Font->Surface->h-1;
  79. srcrect.x = (Font->CharPos[ofs]+Font->CharPos[ofs-1])/2;
  80. srcrect.y = 1;
  81. dstrect.x = x-(float)(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
  82. dstrect.y = y;
  83. SDL_BlitSurface( Font->Surface, &srcrect, Surface, &dstrect);
  84. x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
  85. i++;
  86. }
  87. }
  88. }
  89. void PutString(SDL_Surface *Surface, int x, int y, char *text)
  90. {
  91. PutString2(Surface, &InternalFont, x, y, text);
  92. }
  93. int TextWidth2(SFont_FontInfo *Font, char *text)
  94. {
  95. int ofs=0;
  96. int i=0,x=0;
  97. while (text[i]!='\0') {
  98. if (text[i]==' ') {
  99. x+=Font->CharPos[2]-Font->CharPos[1];
  100. i++;
  101. }
  102. else {
  103. // ofs=(text[i]-33)*2+1;
  104. ofs=((unsigned char)text[i]-33)*2+1;
  105. x+=Font->CharPos[ofs+1]-Font->CharPos[ofs];
  106. i++;
  107. }
  108. }
  109. // printf ("--%d\n",x);
  110. return x;
  111. }
  112. int TextWidth(char *text)
  113. {
  114. return TextWidth2(&InternalFont, text);
  115. }
  116. void XCenteredString2(SDL_Surface *Surface, SFont_FontInfo *Font, int y, char *text)
  117. {
  118. PutString2(Surface, Font, Surface->w/2-TextWidth2(Font,text)/2, y, text);
  119. }
  120. void XCenteredString(SDL_Surface *Surface, int y, char *text)
  121. {
  122. XCenteredString2(Surface, &InternalFont, y, text);
  123. }
  124. void SFont_InternalInput( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
  125. {
  126. SDL_Event event;
  127. int ch=-1,blink=0;
  128. long blinktimer=0;
  129. SDL_Surface *Back;
  130. SDL_Rect rect;
  131. int previous;
  132. // int ofs=(text[0]-33)*2+1;
  133. // int leftshift=(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2;
  134. Back = SDL_AllocSurface(Dest->flags,
  135. Dest->w,
  136. Font->h,
  137. Dest->format->BitsPerPixel,
  138. Dest->format->Rmask,
  139. Dest->format->Gmask,
  140. Dest->format->Bmask, 0);
  141. rect.x=0;
  142. rect.y=y;
  143. rect.w=Dest->w;
  144. rect.h=Font->Surface->h;
  145. SDL_BlitSurface(Dest, &rect, Back, NULL);
  146. XCenteredString2(Dest,Font,/*x,*/y,text);
  147. SDL_UpdateRects(Dest, 1, &rect);
  148. // start input
  149. previous=SDL_EnableUNICODE(1);
  150. blinktimer=SDL_GetTicks();
  151. while (ch!=SDLK_RETURN) {
  152. if (event.type==SDL_KEYDOWN) {
  153. ch=event.key.keysym.unicode;
  154. if (((ch>31)||(ch=='\b')) && (ch<128)) {
  155. if ((ch=='\b')&&(strlen(text)>0))
  156. text[strlen(text)-1]='\0';
  157. else if (ch!='\b')
  158. sprintf(text + strlen(text),"%c",ch);
  159. /* quick hack to use limited number of characters rather than
  160. * pixels - Michael Speck */
  161. if (strlen(text)/*TextWidth2(Font,text)*/>PixelWidth)
  162. text[PixelWidth/*strlen(text)*/]='\0';
  163. SDL_BlitSurface( Back, NULL, Dest, &rect);
  164. XCenteredString2(Dest, Font, /*x,*/ y, text);
  165. SDL_UpdateRects(Dest, 1, &rect);
  166. // printf("%s ## %d\n",text,strlen(text));
  167. SDL_WaitEvent(&event);
  168. }
  169. }
  170. if (SDL_GetTicks()>blinktimer) {
  171. blink=1-blink;
  172. blinktimer=SDL_GetTicks()+500;
  173. if (blink) {
  174. PutString2(Dest, Font, x+TextWidth2(Font,text)/2, y, "|");
  175. SDL_UpdateRects(Dest, 1, &rect);
  176. // SDL_UpdateRect(Dest, x+TextWidth2(Font,text), y, TextWidth2(Font,"|"), Font->Surface->h);
  177. } else {
  178. SDL_BlitSurface( Back, NULL, Dest, &rect);
  179. XCenteredString2(Dest, Font, /*x,*/ y, text);
  180. SDL_UpdateRects(Dest, 1, &rect);
  181. // SDL_UpdateRect(Dest, x-(Font->CharPos[ofs]-Font->CharPos[ofs-1])/2, y, PixelWidth, Font->Surface->h);
  182. }
  183. }
  184. SDL_Delay(1);
  185. SDL_PollEvent(&event);
  186. }
  187. text[strlen(text)]='\0';
  188. SDL_FreeSurface(Back);
  189. SDL_EnableUNICODE(previous); //restore the previous state
  190. }
  191. void SFont_Input2( SDL_Surface *Dest, SFont_FontInfo *Font, int x, int y, int PixelWidth, char *text)
  192. {
  193. SFont_InternalInput( Dest, Font, x, y, PixelWidth, text);
  194. }
  195. void SFont_Input( SDL_Surface *Dest, int x, int y, int PixelWidth, char *text)
  196. {
  197. SFont_Input2( Dest, &InternalFont, x, y, PixelWidth, text);
  198. }