// Freetype2 ext4hge implementations -*- C++ -*- #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; xofst=slot->bitmap_left; yofst=slot->bitmap.rows-slot->bitmap_top; 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;ibitmap.rows;++i) for(int j=0;jbitmap.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.blend=BLEND_ALPHABLEND; 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+yofst; quad.v[1].x=x+rw;quad.v[1].y=y-rh+yofst; quad.v[2].x=x+rw;quad.v[2].y=y+yofst; quad.v[3].x=x;quad.v[3].y=y+yofst; 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(); } } }