00001
00027 #ifndef _HFONT_
00028 #define _HFONT_
00029
00030 #include "main.h"
00031 #include "structures.h"
00032
00033 #include <ft2build.h>
00034 #include <freetype2/freetype/freetype.h>
00035 #include <freetype2/freetype/ftglyph.h>
00036 #include <freetype2/freetype/ftoutln.h>
00037 #include <freetype2/freetype/fttrigon.h>
00038
00039 #include "Colorable.h"
00040
00041 class CFont: public CColorable {
00042
00043 public:
00044
00045 CFont();
00046 CFont(const char *fileName, unsigned int size);
00047 ~CFont();
00048
00049 void loadFont(const char *fileName, unsigned int h) {
00050
00051 textures = new GLuint[128];
00052 this->height = h;
00053
00054 FT_Library library;
00055
00056
00057 if (FT_Init_FreeType(&library)) {
00058 cerr << "FT_Init_Freetype failed" << endl;
00059 }
00060
00061 FT_Face face;
00062
00063
00064 if (FT_New_Face(library, fileName, 0, &face)) {
00065 cerr << "FT_New_Face failed" << endl;
00066 }
00067
00068
00069
00070 FT_Set_Char_Size(face, h << 6, h << 6, 96, 96);
00071
00072
00073 listBase = glGenLists(128);
00074 glGenTextures(128, textures);
00075
00076
00077 for (unsigned char i = 0; i < 128; i++)
00078 makeDList(face, i, listBase, textures);
00079
00080 FT_Done_Face(face);
00081 FT_Done_FreeType(library);
00082
00083 cout << "Font " << fileName << " loading ... success" << endl;
00084
00085 }
00086
00087 void clean();
00088
00089 void print(float x, float y, const char *ftm, ...);
00090 void print(float x, float y, string str);
00091
00092 inline int nextPowerTwo(int a) {
00093 int rval = 1;
00094 while (rval < a)
00095 rval <<= 1;
00096
00097 return rval;
00098 }
00099 ;
00100
00101 void makeDList(FT_Face face, char ch, GLuint listBase, GLuint* texBase) {
00102
00103
00104 if (FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_DEFAULT)) {
00105 cerr << "FT_Load_Glyph failed" << endl;
00106 }
00107
00108 FT_Glyph glyph;
00109
00110 if (FT_Get_Glyph(face -> glyph, &glyph)) {
00111 cerr << "FT_Get_Glyph failed" << endl;
00112 }
00113
00114
00115 FT_Glyph_To_Bitmap(&glyph, ft_render_mode_normal, 0, 1);
00116 FT_BitmapGlyph bitmapGlyph = (FT_BitmapGlyph) glyph;
00117
00118 FT_Bitmap& bitmap = bitmapGlyph->bitmap;
00119
00120 int width = nextPowerTwo(bitmap.width);
00121 int height = nextPowerTwo(bitmap.rows);
00122
00123 GLubyte* expandedData = new GLubyte[2 * width * height];
00124
00125
00126
00127 for (int j = 0; j < height; j++) {
00128 for (int i = 0; i < width; i++) {
00129
00130 expandedData[2 * (i + j * width)] = expandedData[2 * (i + j
00131 * width) + 1]
00132 = (i >= bitmap.width || j >= bitmap.rows) ? 0
00133 : bitmap . buffer[i + bitmap . width * j];
00134
00135 }
00136 }
00137
00138
00139
00140 glBindTexture(GL_TEXTURE_2D, texBase[(int) ch]);
00141 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00142 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00143
00144 glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, width, height, 0,
00145 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expandedData);
00146
00147 delete[] expandedData;
00148
00149 glNewList(listBase + ch, GL_COMPILE);
00150
00151 glBindTexture(GL_TEXTURE_2D, texBase[(int) ch]);
00152
00153 glPushMatrix();
00154
00155 glTranslatef(bitmapGlyph -> left, 0, 0);
00156 glTranslatef(0, bitmapGlyph -> top - bitmap . rows, 0);
00157
00158 float x = (float) bitmap.width / (float) width;
00159 float y = (float) bitmap.rows / (float) height;
00160
00161 glBegin(GL_QUADS);
00162 glTexCoord2d(0, 0);
00163 glVertex2f(0, bitmap.rows);
00164 glTexCoord2d(0, y);
00165 glVertex2f(0, 0);
00166 glTexCoord2d(x, y);
00167 glVertex2f(bitmap.width, 0);
00168 glTexCoord2d(x, 0);
00169 glVertex2f(bitmap.width, bitmap.rows);
00170 glEnd();
00171
00172 glPopMatrix();
00173
00174 glTranslatef(face->glyph->advance.x >> 6, 0, 0);
00175
00176 glEndList();
00177
00178 }
00179 ;
00180
00181 inline void pushScreenCoordinateMatrix() {
00182
00183 glPushAttrib(GL_TRANSFORM_BIT);
00184 GLint viewport[4];
00185 glGetIntegerv(GL_VIEWPORT, viewport);
00186
00187 glMatrixMode(GL_PROJECTION);
00188 glPushMatrix();
00189 glLoadIdentity();
00190 gluOrtho2D(viewport[0], viewport[2], viewport[1], viewport[3]);
00191
00192 glPopAttrib();
00193
00194 }
00195 ;
00196
00197 inline void popProjectionMatrix() {
00198
00199 glPushAttrib(GL_TRANSFORM_BIT);
00200 glMatrixMode(GL_PROJECTION);
00201
00202 glPopMatrix();
00203 glPopAttrib();
00204
00205 }
00206 ;
00207
00208 private:
00209 float height;
00210 GLuint* textures;
00211 GLuint listBase;
00212
00213 };
00214
00215 #endif