I’ve posted it before, but here it is again:On Wed, 2004-12-08 at 15:34, Koshmaar wrote:
If you manage to manage to get this written, would you mind sharing your
code ?-)
Well, you know, my engine is open source… you know the answer Though I will start doing it after 2 weeks or so, in this case maybe Bob Pendleton could share his version (and I would be interested in it too).
Koshmaar
class Font
{
private:
static const int minGlyph = ’ ';
static const int maxGlyph = 126;
static int initCounter;
typedef struct
{
int minx, maxx;
int miny, maxy;
int advance;
SDL_Surface *pic;
GLuint tex;
GLfloat texMinX, texMinY;
GLfloat texMaxX, texMaxY;
} glyph;
int height;
int ascent;
int descent;
int lineSkip;
glyph glyphs[maxGlyph + 1];
unsigned char *address;
int length;
int pointSize;
int style;
float fgRed, fgGreen, fgBlue;
float bgRed, bgGreen, bgBlue;
TTF_Font *ttfFont;
SDL_Color foreground;
SDL_Color background;
void loadChar(char c)
{
GLfloat texcoord[4];
char letter[2] = {0, 0};
if ((minGlyph <= c) &&
(c <= maxGlyph) &&
(NULL == glyphs[((int)c)].pic))
{
SDL_Surface *g0 = NULL;
SDL_Surface *g1 = NULL;
letter[0] = c;
TTF_GlyphMetrics(ttfFont,
(Uint16)c,
&glyphs[((int)c)].minx,
&glyphs[((int)c)].maxx,
&glyphs[((int)c)].miny,
&glyphs[((int)c)].maxy,
&glyphs[((int)c)].advance);
g0 = TTF_RenderText_Shaded(ttfFont,
letter,
foreground,
background);
if (NULL != g0)
{
g1 = SDL_DisplayFormat(g0);
SDL_FreeSurface(g0);
}
if (NULL != g1)
{
glyphs[((int)c)].pic = g1;
glyphs[((int)c)].tex = loadTextureColorKey(g1, texcoord, 0, 0,
0);
glyphs[((int)c)].texMinX = texcoord[0];
glyphs[((int)c)].texMinY = texcoord[1];
glyphs[((int)c)].texMaxX = texcoord[2];
glyphs[((int)c)].texMaxY = texcoord[3];
}
}
}
public:
Font(unsigned char *address,
int length,
int pointSize,
int style,
float fgRed, float fgGreen, float fgBlue,
float bgRed, float bgGreen, float bgBlue):
address(address), length(length),
pointSize(pointSize),
style(style),
fgRed(fgRed), fgGreen(fgGreen), fgBlue(fgBlue),
bgRed(bgRed), bgGreen(bgGreen), bgBlue(bgBlue),
ttfFont(NULL)
{
if (0 == initCounter)
{
if (TTF_Init() < 0)
{
errorExit(“Can’t init SDL_ttf”);
}
}
initCounter++;
initFont();
}
~Font()
{
initCounter–;
if (0 == initCounter)
{
TTF_Quit();
}
}
void initFont()
{
SDL_RWops *src = NULL;
int i;
src = SDL_RWFromMem(address, length);
ttfFont = TTF_OpenFontRW(src, 1, pointSize);
if (NULL == ttfFont)
{
errorExit("Can't open font file");
}
TTF_SetFontStyle(ttfFont, style);
foreground.r = (Uint8)(255 * fgRed);
foreground.g = (Uint8)(255 * fgGreen);
foreground.b = (Uint8)(255 * fgBlue);
background.r = (Uint8)(255 * bgRed);
background.g = (Uint8)(255 * bgGreen);
background.b = (Uint8)(255 * bgBlue);
height = TTF_FontHeight(ttfFont);
ascent = TTF_FontAscent(ttfFont);
descent = TTF_FontDescent(ttfFont);
lineSkip = TTF_FontLineSkip(ttfFont);
for (i = minGlyph; i <= maxGlyph; i++)
{
glyphs[i].pic = NULL;
glyphs[i].tex = 0;
}
}
int getLineSkip()
{
return lineSkip;
}
int getHeight()
{
return height;
}
void textSize(char *text,
SDL_Rect *r)
{
int maxx = 0;
int advance = 0;
r->x = 0;
r->y = 0;
r->w = 0;
r->h = height;
while (0 != *text)
{
if ((minGlyph <= *text) && (*text <= maxGlyph))
{
loadChar(*text);
maxx = glyphs[((int)*text)].maxx;
advance = glyphs[((int)*text)].advance;
r->w += advance;
}
text++;
}
r->w = r->w - advance + maxx;
}
void drawText(char *text, int x, int y)
{
GLfloat left, right;
GLfloat top, bottom;
GLfloat texMinX, texMinY;
GLfloat texMaxX, texMaxY;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_TEXTURE_2D);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
while (0 != *text)
{
if ((minGlyph <= *text) && (*text <= maxGlyph))
{
loadChar(*text);
texMinX = glyphs[((int)*text)].texMinX;
texMinY = glyphs[((int)*text)].texMinY;
texMaxX = glyphs[((int)*text)].texMaxX;
texMaxY = glyphs[((int)*text)].texMaxY;
left = x;
right = x + glyphs[((int)*text)].pic->w;
top = y;
bottom = y + glyphs[((int)*text)].pic->h;
glBindTexture(GL_TEXTURE_2D, glyphs[((int)*text)].tex);
glBegin(GL_TRIANGLE_STRIP);
glTexCoord2f(texMinX, texMinY); glVertex2f( left, top);
glTexCoord2f(texMaxX, texMinY); glVertex2f(right, top);
glTexCoord2f(texMinX, texMaxY); glVertex2f( left, bottom);
glTexCoord2f(texMaxX, texMaxY); glVertex2f(right, bottom);
glEnd();
x += glyphs[((int)*text)].advance;
}
text++;
}
glPopAttrib();
}
};
//-------------------------------------------------
int Font::initCounter = 0;
//-------------------------------------------------
The code is designed so you can just drop it into an existing C++
program. If you are picky about .h and .cpp division you’ll need to
figure that out for your self. And, if you are working in C then, well
you’ll have to convert it.
BTW, it is covered by the LGPL
Bob Pendleton
SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl
–
±-------------------------------------+