Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


for reference: Using SDL_ttf with OpenGL


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
25 replies to this topic

#21 cyberpuk   Members   -  Reputation: 122

Like
0Likes
Like

Posted 20 December 2005 - 05:08 AM

Thank you very much. The two things run very well!.

Sponsor:

#22 kaolin fire   Members   -  Reputation: 122

Like
0Likes
Like

Posted 20 June 2006 - 10:58 PM

I've been tinkering with Bob Pendleton's SDL_ttf font class and made it support newlines... I also took out a few things that I wasn't using, do forgive... it should be pretty obvious how to mix/match :) [[and I split it into the .h and .cpp, and took out the 'background color', instead using alpha blending, and... not sure what else, TBH, sorry]]

### font.h ###

/** BTW, it is covered by the LGPL ** Bob Pendleton **/
/** http://www.devolution.com/pipermail/sdl/2004-December/066119.html **/

/**

+--------------------------------------+
+ Bob Pendleton: writer and programmer +
+ email: Bob@xxxxxxxxxxxxx +
+ blog: www.Stonewolf.net +
+ web: www.GameProgrammer.com +
+--------------------------------------+

http://www.oreillynet.com/pub/au/1205

Edits by Kaolin Fire ( kfire@xxxxxxxx; web: erif.org )
now takes into account glyph minx so glyphs can overlap as intended
now takes into account newline character

**/


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];

const char *fontName;
int pointSize;
float fgRed, fgGreen, fgBlue;

TTF_Font *ttfFont;

SDL_Color foreground;

void loadChar(char c);

public:

Font(const char *fontName,
int pointSize,
float fgRed, float fgGreen, float fgBlue);

~Font();

void initFont();

int getLineSkip();

int getHeight();

void textSize(char *text, SDL_Rect *r);

void drawText(char *text, int x, int y);

};



###font.cpp###

#include "font.h"

void Font::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_Blended(ttfFont,
letter,
foreground);

if (NULL != g0)
{
g1 = SDL_DisplayFormatAlpha(g0);
SDL_FreeSurface(g0);
}

if (NULL != g1)
{
glyphs[((int)c)].pic = g1;
glyphs[((int)c)].tex = SDL_GL_LoadTexture(g1, texcoord);
glyphs[((int)c)].texMinX = texcoord[0];
glyphs[((int)c)].texMinY = texcoord[1];
glyphs[((int)c)].texMaxX = texcoord[2];
glyphs[((int)c)].texMaxY = texcoord[3];
}
}
}

Font::Font(const char *fontName,
int pointSize,
float fgRed, float fgGreen, float fgBlue):
fontName(fontName),
pointSize(pointSize),
fgRed(fgRed), fgGreen(fgGreen), fgBlue(fgBlue),
ttfFont(NULL)
{
if (0 == initCounter)
{
if (TTF_Init() < 0)
{
//TODO :: errorExit("Can't init SDL_ttf");
printf("Can't init sdl_ttf !?\n");
}
}
initCounter++;
initFont();
}

Font::~Font()
{
initCounter--;
if (0 == initCounter)
{
TTF_Quit();
}
}

void Font::initFont()
{
int i;

ttfFont = TTF_OpenFont(fontName, pointSize);
if (NULL == ttfFont)
{
printf("Can't open font file\n");
//TODO :: errorExit("Can't open font file");
}

foreground.r = (Uint8)(255 * fgRed);
foreground.g = (Uint8)(255 * fgGreen);
foreground.b = (Uint8)(255 * fgBlue);

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 Font::getLineSkip()
{
return lineSkip;
}

int Font::getHeight()
{
return height;
}

void Font::textSize(char *text,
SDL_Rect *r)
{
int maxx = 0;
int advance = 0;
int minx = 0;
int w_largest = 0;
char lastchar = 0;

r->x = 0;
r->y = 0;
r->w = 0;
r->h = height;

while (0 != *text)
{
if ((minGlyph <= *text) && (*text <= maxGlyph))
{
lastchar = *text;
if (*text == '\n') {
r->h += lineSkip;
r->w = r->w - advance + maxx;
if (r->w > w_largest) w_largest = r->w;
r->w = 0;
} else {
loadChar(*text);

maxx = glyphs[((int)*text)].maxx;
advance = glyphs[((int)*text)].advance;
r->w += advance;
}
}

text++;
}
if (lastchar != '\n') {
r->w = r->w - advance + maxx;
if (r->w > w_largest) w_largest = r->w;
} else {
r->h -= lineSkip;
}

if (w_largest > r->w) r->w = w_largest;

}

void Font::drawText(char *text, int x, int y)
{
GLfloat left, right;
GLfloat top, bottom;
GLfloat texMinX, texMinY;
GLfloat texMaxX, texMaxY;
GLfloat minx;
GLfloat baseleft = x;

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 (*text == '\n') {
x = baseleft;
y += lineSkip;
} else 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;

minx = glyphs[((int)*text)].minx;

left = x + minx;
right = x + glyphs[((int)*text)].pic->w + minx;
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;



#23 mattn   Members   -  Reputation: 122

Like
0Likes
Like

Posted 03 July 2006 - 06:53 AM

i wonder whether this works with uft-8, too?

#24 Anonymous Poster_Anonymous Poster_*   Guests   -  Reputation:

0Likes

Posted 17 January 2007 - 07:12 AM

Hi,
Sorry for the UP but I want to know how to use this code with Latin specials chars like "é" "ê" "à" ?

#25 Garkader   Members   -  Reputation: 122

Like
0Likes
Like

Posted 04 August 2008 - 10:50 PM

@kaolin fire
function Font::textSize is not handling newlines properly.
The first condition in the while loop should be corrected to something like:

if (((minGlyph <= *text) && (*text <= maxGlyph)) || *text == '\n')

instead of

if ((minGlyph <= *text) && (*text <= maxGlyph))

Otherwise '\n' won't be processed.

#26 deek0146   Members   -  Reputation: 100

Like
0Likes
Like

Posted 28 February 2011 - 07:22 AM

Thank you, that works instantly! I just called RenderText_Blended and (when I passed it into my gl texture creation function) it just returned a texture all of the colour passed into the TTF function.

Also Koshmaar thanks for the management system, saved me a lot of time :)




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS