Advertisement
WeltEnSTurm

Untitled

Oct 19th, 2011
399
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.55 KB | None | 0 0
  1. // File: font.cpp, created on Sep 1, 2011 by WeltEnSTurm
  2.  
  3. #include "gui/font.hpp"
  4. #include "tools/exception.hpp"
  5.  
  6. inline int next_p2 (int a){
  7.     int rval=1;
  8.     while(rval<a) rval<<=1;
  9.     return rval;
  10. }
  11.  
  12. fm::~fm(){
  13.     for(font* f: Fonts){
  14.         for(font::Glyph* g: f->Data)
  15.             delete g;
  16.         delete f;
  17.     }
  18. }
  19.  
  20. #pragma pack(1)
  21. struct TGAHEADER {
  22.     GLbyte  identsize;              // Size of ID field that follows header (0)
  23.     GLbyte  colorMapType;           // 0 = None, 1 = paletted
  24.     GLbyte  imageType;              // 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle
  25.     unsigned short  colorMapStart;  // First colour map entry
  26.     unsigned short  colorMapLength; // Number of colors
  27.     unsigned char   colorMapBits;   // bits per palette entry
  28.     unsigned short  xstart;         // image x origin
  29.     unsigned short  ystart;         // image y origin
  30.     unsigned short  width;          // width in pixels
  31.     unsigned short  height;         // height in pixels
  32.     GLbyte  bits;                   // bits per pixel (8 16, 24, 32)
  33.     GLbyte  descriptor;             // image descriptor
  34. };
  35. #pragma pack(8)
  36.  
  37. void saveChar(const std::string& file, int width, int height, void* data){
  38.     TGAHEADER tgaHeader = {
  39.             0, 0, 2,
  40.             0, 0, 0,
  41.             0, 0,
  42.             (short)width,
  43.             (short)height,
  44.             32, 1<<5
  45.     };
  46.  
  47.     FILE* pFile= fopen(("fonts/"+file).c_str(), "wb");
  48.     if(!pFile)
  49.         return;
  50.  
  51.     fwrite(&tgaHeader, 18, 1, pFile);
  52.  
  53.     fwrite(data, height*width*4, 1, pFile);
  54.     fclose(pFile);
  55. }
  56.  
  57. fm::font* fm::LoadFont(std::string path, long size, long index){
  58.     FT_Error ret = FT_Init_FreeType(&Get().mLib);
  59.     if(ret)
  60.         error("Failed to initialize FreeType 2. Error code " << (int)ret);
  61.  
  62.     for(font* f: Get().Fonts)
  63.         if(f->Path == path && f->Index == index)
  64.             return f;
  65.  
  66.     FT_Face face;
  67.     ret = FT_New_Face(
  68.         Get().mLib,
  69.         path.c_str(),
  70.         index,
  71.         &face
  72.     );
  73.  
  74.     if(ret == FT_Err_Unknown_File_Format){
  75.         error("Failed to load font. File format is unknown.");
  76.     }else if(ret){
  77.         error("Failed to load font. Error code " << (int)ret);
  78.     }else{
  79.         Get().Fonts.push_back(new font());
  80.         font& f = *Get().Fonts.back();
  81.  
  82.         FT_Set_Char_Size(face, size << 6, size << 6, 96, 96);
  83.  
  84.         f.Face = face;
  85.         f.Path = path;
  86.         f.Index = index;
  87.         f.init();
  88.  
  89.         FT_Done_Face(face);
  90.         return &f;
  91.     }
  92.     FT_Done_FreeType(Get().mLib);
  93.  
  94.     return 0;
  95. }
  96.  
  97. void fm::font::init(){
  98.     if(Invalid) return;
  99.  
  100.     for(long i=0; i<128; i++){
  101.         Data.push_back(new Glyph());
  102.         Glyph& g = *Data.back();
  103.  
  104.         FT_Error e = FT_Load_Glyph(Face, FT_Get_Char_Index(Face, (char)i), FT_LOAD_DEFAULT);
  105.         if(e){
  106.             error("FT_Load_Glyph failed (" << e << ")");
  107.             return;
  108.         }
  109.         FT_Glyph glyph;
  110.         e = FT_Get_Glyph(Face->glyph, &glyph);
  111.         if(e){
  112.             error("FT_Get_Glyph failed (" << e << ")");
  113.             return;
  114.         }
  115.  
  116.         FT_Glyph_To_Bitmap(&glyph, FT_RENDER_MODE_NORMAL, 0, 1);
  117.         FT_Bitmap& bitmap = ((FT_BitmapGlyph)glyph)->bitmap;
  118.  
  119.         int width = bitmap.width;
  120.         int height = bitmap.rows;
  121.  
  122.         /*
  123.         int width = next_p2(bitmap.width);
  124.         int height = next_p2(bitmap.rows);
  125.         */
  126.  
  127.         GLubyte* expandedData = new GLubyte[width * height * 4];
  128.  
  129.         /*
  130.         for(int j=0; j <height; j++)
  131.             for(int i=0; i < width; i++){
  132.                 expandedData[2*(i+j*width)] =
  133.                 expandedData[2*(i+j*width)+1] =
  134.                 expandedData[2*(i+j*width)+2] =
  135.                     (i>=bitmap.width || j>=bitmap.rows) ? 0 : bitmap.buffer[i + bitmap.width*j];
  136.                 expandedData[2*(i+j*width)+4] = 1;
  137.             }
  138.         */
  139.  
  140.         for(int y=0; y < height; y++){
  141.             for(int x=0; x < width; x++){
  142.                 byte* pixel = &expandedData[(x + y*width)*4];
  143.                 pixel[0] =
  144.                 pixel[1] =
  145.                 pixel[2] =
  146.                 pixel[3] =
  147.                     (x>=bitmap.width || y>=bitmap.rows) ? 0 : bitmap.buffer[x + y*bitmap.width];
  148.                 //pixel[3] = 255;
  149.             }
  150.         }
  151.  
  152.         gl.GenTextures(1, &g.Map);
  153.         gl.BindTexture(GL_TEXTURE_RECTANGLE, g.Map);
  154.         gl.TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  155.         gl.TexParameteri(GL_TEXTURE_RECTANGLE, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  156.         gl.TexImage2D(
  157.             GL_TEXTURE_RECTANGLE, 0, GL_RGBA, width, height, 0,
  158.             GL_RGBA, GL_UNSIGNED_BYTE, expandedData
  159.         );
  160.         gl.BindTexture(GL_TEXTURE_RECTANGLE, 0);
  161.  
  162.         std::string name = " .tga";
  163.         name[0] = i;
  164.  
  165.         saveChar(name, width, height, expandedData);
  166.  
  167.         delete[] expandedData;
  168.  
  169.         g.Width = width;
  170.         g.Height = height;
  171.  
  172.         g.Vertices.Begin(GL_TRIANGLE_FAN, 4, 1);
  173.         g.Vertices.MultiTexCoord2f(0, 0, 0);
  174.         g.Vertices.Vertex3f(0, 0, 0);
  175.  
  176.         g.Vertices.MultiTexCoord2f(0, width, 0);
  177.         g.Vertices.Vertex3f(width, 0, 0);
  178.  
  179.         g.Vertices.MultiTexCoord2f(0, width, height);
  180.         g.Vertices.Vertex3f(width, height, 0);
  181.  
  182.         g.Vertices.MultiTexCoord2f(0, 0, height);
  183.         g.Vertices.Vertex3f(0, height, 0);
  184.         g.Vertices.End();
  185.  
  186.     }
  187.  
  188. }
  189.  
  190.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement