2 * Written By: Garrett Banuk <mongoose@mongeese.org>
3 * This is free, just be sure to give me credit when using it
4 * in any of your programs.
11 #include "SDL_image.h"
12 #include "DT_drawtext.h"
16 static BitFont *BitFonts = NULL; /* Linked list of fonts */
19 /* sets the transparency value for the font in question. assumes that
20 * we're in an OpenGL context. */
21 void DT_SetFontAlphaGL(int FontNumber, int a) {
24 unsigned char r_targ, g_targ, b_targ;
28 /* get pointer to font */
29 CurrentFont = DT_FontPointer(FontNumber);
30 if(CurrentFont == NULL) {
31 PRINT_ERROR("Setting font alpha for non-existent font!\n");
34 if(CurrentFont->FontSurface->format->BytesPerPixel == 2) {
35 PRINT_ERROR("16-bit SDL surfaces do not support alpha-blending under OpenGL\n");
38 if(a < SDL_ALPHA_TRANSPARENT)
39 val = SDL_ALPHA_TRANSPARENT;
40 else if(a > SDL_ALPHA_OPAQUE)
41 val = SDL_ALPHA_OPAQUE;
45 /* iterate over all pixels in the font surface. For each
46 * pixel that is (255,0,255), set its alpha channel
48 imax = CurrentFont->FontSurface->h * (CurrentFont->FontSurface->w << 2);
49 pix = (unsigned char *)(CurrentFont->FontSurface->pixels);
50 r_targ = 255; /*pix[0]; */
51 g_targ = 0; /*pix[1]; */
52 b_targ = 255; /*pix[2]; */
53 for(i = 3; i < imax; i += 4)
54 if(pix[i - 3] == r_targ && pix[i - 2] == g_targ && pix[i - 1] == b_targ)
56 /* also make sure that alpha blending is disabled for the font
58 SDL_SetAlpha(CurrentFont->FontSurface, 0, SDL_ALPHA_OPAQUE);
61 /* Loads the font into a new struct
62 * returns -1 as an error else it returns the number
63 * of the font for the user to use
65 int DT_LoadFont(const char *BitmapName, int flags) {
67 BitFont **CurrentFont = &BitFonts;
72 CurrentFont = &((*CurrentFont)->NextFont);
76 /* load the font bitmap */
77 if(NULL == (Temp = IMG_Load(BitmapName))) {
78 PRINT_ERROR("Cannot load file ");
79 printf("%s\n", BitmapName);
83 /* Add a font to the list */
84 *CurrentFont = (BitFont *) malloc(sizeof(BitFont));
86 (*CurrentFont)->FontSurface = SDL_DisplayFormat(Temp);
87 SDL_FreeSurface(Temp);
89 (*CurrentFont)->CharWidth = (*CurrentFont)->FontSurface->w / 256;
90 (*CurrentFont)->CharHeight = (*CurrentFont)->FontSurface->h;
91 (*CurrentFont)->FontNumber = FontNumber;
92 (*CurrentFont)->NextFont = NULL;
95 /* Set font as transparent if the flag is set. The assumption we'll go on
96 * is that the first pixel of the font image will be the color we should treat
99 if(flags & TRANS_FONT) {
100 if(SDL_GetVideoSurface()->flags & SDL_OPENGLBLIT)
101 DT_SetFontAlphaGL(FontNumber, SDL_ALPHA_TRANSPARENT);
103 SDL_SetColorKey((*CurrentFont)->FontSurface, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB((*CurrentFont)->FontSurface->format, 255, 0, 255));
104 } else if(SDL_GetVideoSurface()->flags & SDL_OPENGLBLIT)
105 DT_SetFontAlphaGL(FontNumber, SDL_ALPHA_OPAQUE);
110 /* Takes the font type, coords, and text to draw to the surface*/
111 void DT_DrawText(const char *string, SDL_Surface *surface, int FontType, int x, int y) {
115 SDL_Rect SourceRect, DestRect;
116 BitFont *CurrentFont;
118 CurrentFont = DT_FontPointer(FontType);
120 /* see how many characters can fit on the screen */
121 if(x > surface->w || y > surface->h)
124 if(strlen(string) < (surface->w - x) / CurrentFont->CharWidth)
125 characters = strlen(string);
127 characters = (surface->w - x) / CurrentFont->CharWidth;
131 DestRect.w = CurrentFont->CharWidth;
132 DestRect.h = CurrentFont->CharHeight;
135 SourceRect.w = CurrentFont->CharWidth;
136 SourceRect.h = CurrentFont->CharHeight;
139 for(loop = 0; loop < characters; loop++) {
140 current = string[loop];
141 if (current<0 || current > 255)
143 //SourceRect.x = string[loop] * CurrentFont->CharWidth;
144 SourceRect.x = current * CurrentFont->CharWidth;
145 SDL_BlitSurface(CurrentFont->FontSurface, &SourceRect, surface, &DestRect);
146 DestRect.x += CurrentFont->CharWidth;
148 /* if we're in OpenGL-mode, we need to manually update after blitting. */
149 if(surface->flags & SDL_OPENGLBLIT) {
151 DestRect.w = characters * CurrentFont->CharWidth;
152 SDL_UpdateRects(surface, 1, &DestRect);
157 /* Returns the height of the font numbers character
158 * returns 0 if the fontnumber was invalid */
159 int DT_FontHeight(int FontNumber) {
160 BitFont *CurrentFont;
162 CurrentFont = DT_FontPointer(FontNumber);
164 return CurrentFont->CharHeight;
169 /* Returns the width of the font numbers charcter */
170 int DT_FontWidth(int FontNumber) {
171 BitFont *CurrentFont;
173 CurrentFont = DT_FontPointer(FontNumber);
175 return CurrentFont->CharWidth;
180 /* Returns a pointer to the font struct of the number
181 * returns NULL if theres an error
183 BitFont *DT_FontPointer(int FontNumber) {
184 BitFont *CurrentFont = BitFonts;
188 if(CurrentFont->FontNumber == FontNumber)
192 CurrentFont = CurrentFont->NextFont;
199 /* removes all the fonts currently loaded */
200 void DT_DestroyDrawText() {
201 BitFont *CurrentFont = BitFonts;
206 CurrentFont = CurrentFont->NextFont;
208 SDL_FreeSurface(temp->FontSurface);