Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // File: font.cpp, created on Sep 1, 2011 by WeltEnSTurm
- #include "gui/font.hpp"
- #include "tools/exception.hpp"
- inline int next_p2 (int a){
- int rval=1;
- while(rval<a) rval<<=1;
- return rval;
- }
- fm::~fm(){
- for(font* f: Fonts){
- for(font::Glyph* g: f->Data)
- delete g;
- delete f;
- }
- }
- #pragma pack(1)
- struct TGAHEADER {
- GLbyte identsize; // Size of ID field that follows header (0)
- GLbyte colorMapType; // 0 = None, 1 = paletted
- GLbyte imageType; // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle
- unsigned short colorMapStart; // First colour map entry
- unsigned short colorMapLength; // Number of colors
- unsigned char colorMapBits; // bits per palette entry
- unsigned short xstart; // image x origin
- unsigned short ystart; // image y origin
- unsigned short width; // width in pixels
- unsigned short height; // height in pixels
- GLbyte bits; // bits per pixel (8 16, 24, 32)
- GLbyte descriptor; // image descriptor
- };
- #pragma pack(8)
- void saveChar(const std::string& file, int width, int height, void* data){
- TGAHEADER tgaHeader = {
- 0, 0, 2,
- 0, 0, 0,
- 0, 0,
- (short)width,
- (short)height,
- 32, 1<<5
- };
- FILE* pFile= fopen(("fonts/"+file).c_str(), "wb");
- if(!pFile)
- return;
- fwrite(&tgaHeader, 18, 1, pFile);
- fwrite(data, height*width*4, 1, pFile);
- fclose(pFile);
- }
- fm::font* fm::LoadFont(std::string path, long size, long index){
- FT_Error ret = FT_Init_FreeType(&Get().mLib);
- if(ret)
- error("Failed to initialize FreeType 2. Error code " << (int)ret);
- for(font* f: Get().Fonts)
- if(f->Path == path && f->Index == index)
- return f;
- FT_Face face;
- ret = FT_New_Face(
- Get().mLib,
- path.c_str(),
- index,
- &face
- );
- if(ret == FT_Err_Unknown_File_Format){
- error("Failed to load font. File format is unknown.");
- }else if(ret){
- error("Failed to load font. Error code " << (int)ret);
- }else{
- Get().Fonts.push_back(new font());
- font& f = *Get().Fonts.back();
- FT_Set_Char_Size(face, size << 6, size << 6, 96, 96);
- f.Face = face;
- f.Path = path;
- f.Index = index;
- f.init();
- FT_Done_Face(face);
- return &f;
- }
- FT_Done_FreeType(Get().mLib);
- return 0;
- }
- void fm::font::init(){
- if(Invalid) return;
- for(long i=0; i<128; i++){
- Data.push_back(new Glyph());
- Glyph& g = *Data.back();
- FT_Error e = FT_Load_Glyph(Face, FT_Get_Char_Index(Face, (char)i), FT_LOAD_DEFAULT);
- if(e){
- error("FT_Load_Glyph failed (" << e << ")");
- return;
- }
- FT_Glyph glyph;
- e = FT_Get_Glyph(Face->glyph, &glyph);
- if(e){
- error("FT_Get_Glyph failed (" << e << ")");
- return;
- }
- FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
- FT_Bitmap& bitmap = ((FT_BitmapGlyph)glyph)->bitmap;
- int width = bitmap.width;
- int height = bitmap.rows;
- /*
- int width = next_p2(bitmap.width);
- int height = next_p2(bitmap.rows);
- */
- GLubyte* expandedData = new GLubyte[width * height * 4];
- /*
- for(int j=0; j <height; j++)
- for(int i=0; i < width; i++){
- expandedData[2*(i+j*width)] =
- expandedData[2*(i+j*width)+1] =
- expandedData[2*(i+j*width)+2] =
- (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
- expandedData[2*(i+j*width)+4] = 1;
- }
- */
- for(int y=0; y < height; y++){
- for(int x=0; x < width; x++){
- byte* pixel = &expandedData[(x + y*width)*4];
- pixel[0] =
- pixel[1] =
- pixel[2] =
- pixel[3] =
- (x>=bitmap.width || y>=bitmap.rows) ? 0 : bitmap.buffer[x + y*bitmap.width];
- //pixel[3] = 255;
- }
- }
- gl.GenTextures(1, &g.Map);
- gl.BindTexture(GL_TEXTURE_RECTANGLE, g.Map);
- gl.TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
- gl.TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
- gl.TexImage2D(
- GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, expandedData
- );
- gl.BindTexture(GL_TEXTURE_RECTANGLE, 0);
- std::string name = " .tga";
- name[0] = i;
- saveChar(name, width, height, expandedData);
- delete[] expandedData;
- g.Width = width;
- g.Height = height;
- g.Vertices.Begin(GL_TRIANGLE_FAN, 4, 1);
- g.Vertices.MultiTexCoord2f(0, 0, 0);
- g.Vertices.Vertex3f(0, 0, 0);
- g.Vertices.MultiTexCoord2f(0, width, 0);
- g.Vertices.Vertex3f(width, 0, 0);
- g.Vertices.MultiTexCoord2f(0, width, height);
- g.Vertices.Vertex3f(width, height, 0);
- g.Vertices.MultiTexCoord2f(0, 0, height);
- g.Vertices.Vertex3f(0, height, 0);
- g.Vertices.End();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement