Jump to content
  • Advertisement
Sign in to follow this  
exextatic

Font Rendering Woes (FreeType)

This topic is 1393 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

Not sure if it's better to post in here or the DirectX forums, but I digress.
 
Just starting out with using FreeType for my font system under DirectX9, and am having horrible results - the output characters look worse than the regular D3DXCreateFont / DrawText methods, for example:
Lower-case 'k':
dLr0yhB.png 
Lower-case 'w':
ddJqagd.png

Currently, all that's happening is the font is being loaded through TrueType, and I'm taking the bitmap it generates and putting it into an IDirect3DTexture9 struct, and then writing it to a file as a jpg.

Here is the code currently in use to do this (non-interesting bits removed, apologies for the generally atrocious code):

CFont::CFont(char* face, int height, int width, bool italic)
{
	FT_Init_FreeType(&library);
	FT_New_Face(library, face, NULL, &fFace);
	FT_Set_Char_Size(fFace, width, height, 300, 300);
	FT_Set_Pixel_Sizes(fFace, 0, 16); //ToDo: Fix this
}

void SetPixel(D3DLOCKED_RECT* rect, int x, int y, D3DCOLOR col)
{
	unsigned char *bits = (unsigned char *)rect->pBits;
	memcpy(&bits[rect->Pitch * y + 4 * x], &col, 4);
}

HRESULT CFont::Draw(char* text, int count, D3DCOLOR colour, DWORD format)
{
	FT_GlyphSlot slot = fFace->glyph;

	for(int n = 0; n < count; n++)
	{
		FT_Set_Char_Size(fFace, 24 << 6, 24 << 6, 300, 300);

		FT_UInt glyph_index = FT_Get_Char_Index(fFace, text[n]);
		if(FT_Load_Glyph(fFace, glyph_index, FT_LOAD_DEFAULT))
			continue;

		if(FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_NORMAL))
			continue;

		LPDIRECT3DTEXTURE9 tmp;
		FT_Bitmap *ftBitmap = &fFace->glyph->bitmap;

		const int height = ftBitmap->rows;
		const int width = ftBitmap->width;

		D3DXCreateTexture(Renderer().GetD3DDev(), width, height, D3DX_DEFAULT, D3DUSAGE_DYNAMIC, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &tmp);

		D3DLOCKED_RECT tmp2;
		tmp->LockRect(0, &tmp2, NULL, D3DLOCK_DISCARD);
		FillMemory(tmp2.pBits, width*height*tmp2.Pitch, 255);
		
		//Code from: http://www.gamedev.net/topic/545202-freetype/
		for(int y = 0; y < height; ++y)
		{
			for(int x = 0; x < width; ++x)
			{
				byte intensity = ftBitmap->buffer[y * ftBitmap->pitch + x];
				byte r = (byte)(0 * intensity);
				byte g = (byte)(255 * intensity);
				byte b = (byte)(0 * intensity);
				SetPixel(&tmp2, x, y, D3DCOLOR_ARGB(255/*intensity*/, r, g, b));
			}
		}

		tmp->UnlockRect(0);

		char finalName[6];
		sprintf(finalName, "%c.jpg", text[n]);
		D3DXSaveTextureToFile(finalName, D3DXIFF_JPG, tmp, NULL);
	}

	return S_OK;
}

 
My question is, how can I improve the output from this code?

I've also attached the whole alphabet's images.
 
Many thanks in advance,

Share this post


Link to post
Share on other sites
Advertisement

I think

byte intensity = ftBitmap->buffer[y * ftBitmap->pitch + x];

should be something like

float intensity = ftBitmap->buffer[y * ftBitmap->pitch + x] / 255.0f;

instead

Share this post


Link to post
Share on other sites

I think

byte intensity = ftBitmap->buffer[y * ftBitmap->pitch + x];

should be something like

float intensity = ftBitmap->buffer[y * ftBitmap->pitch + x] / 255.0f;

instead

Perfect, this fixed it, many thanks :)

 

Are you sure this is not .jpg artifact? I'm not sure how good quality is on those.

I feel that part of the horrible quality it was producing was due to it being a JPG (tried PNG, looks better), but it turns out the actual issue was the data type that the intensity was using. Many thanks for the help though :)

Share this post


Link to post
Share on other sites
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!