summaryrefslogtreecommitdiff
path: root/hgeft.cpp
blob: c067a1fe299e56b6910196e3d38f2061744b0bc6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "hgeft.h"
static const char* HGEFT_SRC_FN="hgeft.cpp";
void hgeTTChar::Free(){if(quad.tex)hge->Texture_Free(quad.tex),quad.tex=0;}
bool hgeTTChar::SetChar(wchar_t ch,FT_Face ttfface)
{
	FT_GlyphSlot slot=ttfface->glyph;
	FT_UInt glyph_index=FT_Get_Char_Index(ttfface,ch);
	FT_Error err=FT_Load_Glyph(ttfface,glyph_index,FT_LOAD_DEFAULT);
	if(err){hge->System_Log("%s: Glyph load failed!",HGEFT_SRC_FN);return false;}
	err=FT_Render_Glyph(ttfface->glyph,FT_RENDER_MODE_NORMAL);
	if(err){hge->System_Log("%s: Glyph render failed!",HGEFT_SRC_FN);return false;}
	_w=slot->advance.x>>6;_h=slot->bitmap.rows;//we are one line only.
	rw=slot->bitmap.width;rh=slot->bitmap.rows;
	quad.tex=hge->Texture_Create(
	slot->bitmap.width?slot->bitmap.width:1,
	slot->bitmap.rows?slot->bitmap.rows:1);
	DWORD* tx=hge->Texture_Lock(quad.tex,false,0,0,
	slot->bitmap.width?slot->bitmap.width:1,
	slot->bitmap.rows?slot->bitmap.rows:1);
	memset(tx,0,sizeof(DWORD)*(slot->bitmap.width?slot->bitmap.width:1)*(slot->bitmap.rows?slot->bitmap.rows:1));
	int ptr=0;
	for(int i=0;i<slot->bitmap.rows;++i)
	for(int j=0;j<slot->bitmap.width;++j)
	{
#ifdef WIN32
		tx[i*slot->bitmap.width+j]=ARGB(slot->bitmap.buffer[ptr],255,255,255);
#else
		tx[(slot->bitmap.rows-i-1)*slot->bitmap.width+j]=ARGB(slot->bitmap.buffer[ptr],255,255,255);
		//In OpenGL, textures are locked upside down...
#endif
		ptr++;
	}
	hge->Texture_Unlock(quad.tex);
	quad.v[0].tx=0;quad.v[0].ty=0;quad.v[1].tx=1;quad.v[1].ty=0;
	quad.v[2].tx=1;quad.v[2].ty=1;quad.v[3].tx=0;quad.v[3].ty=1;
	return true;
}
void hgeTTChar::Render(double x,double y,DWORD col)
{
	for(int i=0;i<4;++i)quad.v[i].col=col;
	quad.v[0].x=x;quad.v[0].y=y-rh;
	quad.v[1].x=x+rw;quad.v[1].y=y-rh;
	quad.v[2].x=x+rw;quad.v[2].y=y;
	quad.v[3].x=x;quad.v[3].y=y;
	hge->Gfx_RenderQuad(&quad);
}
bool hgeTTFont::Init(const char *ttf,int size)
{
	FT_Error err=FT_Init_FreeType(&libft);
	if(err){hge->System_Log("%s: Failed to initialize freetype",HGEFT_SRC_FN);return false;}
	err=FT_New_Face(libft,ttf,0,&ttfface);
	if(err){hge->System_Log("%s: Failed to load font: %s",HGEFT_SRC_FN,ttf);return false;}
	err=FT_Set_Char_Size(ttfface,0,size*64,96,96);
	return true;
}
void hgeTTFont::UpdateString(const wchar_t *format, ...)
{
	for(int i=0;buf[i]!='\0';++i)chars[i].Free();
	memset(buf,0,sizeof(buf));memset(chars,0,sizeof(chars));
	va_list vl;
	va_start(vl,format);
	vswprintf(buf,1024,format,vl);
	va_end(vl);
	buf[1024]='\0';
	w=h=0;
	for(int i=0;buf[i]!='\0';++i)
	{
		chars[i].SetChar(buf[i],ttfface);
		w+=chars[i].w();
		if(chars[i].h()>h)h=chars[i].h();
	}
}
void hgeTTFont::Render(double x,double y,DWORD color,int align)
{
	int cur;
	if(align==0)
	{
		cur=x;
		for(int i=0;buf[i]!='\0';++i)
		{
			chars[i].Render(cur,y,color);
			cur+=chars[i].w();
		}
	}
	if(align==1)
	{
		cur=x;
		for(int i=wcslen(buf)-1;i>=0;--i)
		{
			chars[i].Render(cur,y,color);
			cur-=chars[i].w();
		}
	}
}