Jump to content
  • Advertisement
Sign in to follow this  
NeuralCrack

Freetype char misalignment problems

This topic is 4975 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, --------------background info... skip it if you want------------ First I hesitated about implementing a FreeType engine into my program, and meanwhile I used WGL fonts. Then I thinked: "Hey, it will be good to make the game plattform-independent, so why not to use FreeType?". So I got to work. First I tried to make my way through using the Nehe's FreeType tutorial... Didn't understand it, so I abandoned. Later I tried again, and finally I went up with something that makes sense. ---------------------------------------------------------------- But now I meet a problem: it works well, but the characters are misaligned! I tried all I could, but I couldn't fix it. Could anyone of you take a look at this code and help me to fix the problem? Here is the code of my FreeType library:
/* freetype_lib.c
 * Copyright (C) 2004 NeuralCrack
 */
 
#include <ft2build.h>
#include <freetype/freetype.h>
#include <freetype/ftglyph.h>

/* enum declaration */
typedef enum {
	ftlib_fontFace_regular,
	ftlib_fontFace_bold,
	ftlib_fontFace_italic,
	ftlib_fontFace_boldItalic
} ftlib_fontFaceStyles;

/* struct declaration */
typedef struct {
	FT_Face freetypeFace;
	glTexture textures[255];		/* one for each glyph in the face */
	int height, displayListBase;
} ftlib_fontFace;

typedef struct {
	ftlib_fontFace faces[4];		/* see 'ftlib_fontFaceStyles' enum */
	int height;
} ftlib_font;

/* variable declaration */
char				ftlib_fontPath[255];
FT_Library		ftlib_mainLibrary;

/* function prototypes */
void		ftlib_init(char*, FT_Library*);
void		ftlib_shutdown(FT_Library);
void		ftlib_loadFontFace(char*, int, ftlib_fontFace*, FT_Library);
void		ftlib_print(ftlib_fontFace, unsigned int, unsigned int, char*, ...);

/* function implementations */
void ftlib_init(char fontPath[], FT_Library *lib)
{
	strcpy(ftlib_fontPath, fontPath);
	FT_Init_FreeType(lib);
}

void ftlib_shutdown(FT_Library lib)
{
	FT_Done_FreeType(lib);
	return;
}

void ftlib_loadFontFace(char facePath[], int height, ftlib_fontFace *face, FT_Library lib)
{
	int i, x, y;
	float x2, y2;
	FT_Glyph charGlyph;
	FT_BitmapGlyph charGlyph_bitmap;
	glTexture *currentCharTex;
	
	FT_New_Face(lib, facePath, 0, &face->freetypeFace);
	FT_Set_Char_Size(face->freetypeFace, (height*64), (height*64), 96,96);
	face->height = height;
	face->displayListBase = glGenLists(255);
	
	for(i=0; i<255; i++) {			/* now load all the glyphs inside the given face */
		/* get all the data from FreeType */
		FT_Load_Glyph(face->freetypeFace, FT_Get_Char_Index(face->freetypeFace, i), FT_LOAD_DEFAULT);
		FT_Get_Glyph(face->freetypeFace->glyph, &charGlyph);
		FT_Glyph_To_Bitmap(&charGlyph, FT_RENDER_MODE_NORMAL, 0, true);
		charGlyph_bitmap = (FT_BitmapGlyph) charGlyph;
		
		/* quick access and some cleaning */
		/*face->freetypeBitmapGlyphs = (FT_BitmapGlyphRec) *charGlyph_bitmap;*/
		currentCharTex = &face->textures;
		memset(currentCharTex, 0, sizeof(glTexture));
		
		/* now create a texture with the values FreeType gave to us */
		currentCharTex->width = math_nextp2(charGlyph_bitmap->bitmap.width);	
		currentCharTex->height = math_nextp2(charGlyph_bitmap->bitmap.rows);
		currentCharTex->bpp = 8;	currentCharTex->pixelFormat = GL_RGBA;	currentCharTex->pfBytes_count = 4;
		currentCharTex->data = (unsigned char *) malloc(2*currentCharTex->width*currentCharTex->height);
		
		/* hey, don't ask, this works :) */
		for(y=0; y<(currentCharTex->height); y++) {
			for(x=0; x<(currentCharTex->width); x++) {
				currentCharTex->data[2*(x+y*currentCharTex->width)] = currentCharTex->data[2*(x+y*currentCharTex->width)+1] =
				(x>=charGlyph_bitmap->bitmap.width) || (y>=charGlyph_bitmap->bitmap.rows) ? 0 : charGlyph_bitmap->bitmap.buffer[x+charGlyph_bitmap->bitmap.width*y];
			}
		}
		/* ... */
		glGenTextures(1, ¤tCharTex->glID);
		glBindTexture(GL_TEXTURE_2D, currentCharTex->glID);
		glTexImage2D(GL_TEXTURE_2D, 0, currentCharTex->pfBytes_count, currentCharTex->width, currentCharTex->height, 0, 
								GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, currentCharTex->data);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
								
		/* now we create the display list with the textured quad inside */
		glNewList( (face->displayListBase+i), GL_COMPILE);
			glBindTexture(GL_TEXTURE_2D, currentCharTex->glID);
			glBegin(GL_QUADS);
				glTexCoord2f(0,y2);		glVertex2f(0, charGlyph_bitmap->bitmap.rows);		/* down left */
				glTexCoord2f(0,0);	     glVertex2f(0,0);															/* up left */
				glTexCoord2f(x2,0);     glVertex2f(charGlyph_bitmap->bitmap.width, 0);	/* up right */
				glTexCoord2f(x2,y2);   glVertex2f(charGlyph_bitmap->bitmap.width, charGlyph_bitmap->bitmap.rows);		/* down right */
			glEnd();
		glEndList(); 
		
		/* ok, now it's all done... */
	}
	return;
}

void ftlib_print(ftlib_fontFace face, unsigned int x, unsigned int y, char *fmt, ...)
{
	int charCode, i;
	char text[255];
	va_list ap;
	
	va_start(ap, fmt);
		vsprintf(text, fmt, ap);
	va_end(ap);
	
	glLoadIdentity();
	glTranslatef(x,y,0);
	
	glEnable(GL_TEXTURE_2D);
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		
	for(i=0; i<strlen(text); i++) {
		charCode = text;
		glCallList(face.displayListBase+charCode);
		glTranslatef(face.textures[charCode].width,0,0);
	 }
	 
	glDisable(GL_BLEND);
	glDisable(GL_TEXTURE_2D); 
}



And here's the definition of glTexture:
typedef struct {
	unsigned int width, height, bpp;
	unsigned int pixelFormat, pfBytes_count;
	unsigned int glID;
	unsigned char *data;
} glTexture;


Thanks in advance.

Share this post


Link to post
Share on other sites
Advertisement
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!