00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <GLEXT/GLFont2dFreeType.h>
00022 #include <GLEXT/GLState.h>
00023 #include <common/Defines.h>
00024
00025
00026
00027 static inline int next_p2 (int a )
00028 {
00029 int rval=1;
00030
00031 while(rval<a) rval<<=1;
00032 return rval;
00033 }
00034
00035 GLFont2dFreeType::GLFont2dFreeType() : makeShadow_(false)
00036 {
00037
00038 }
00039
00040 GLFont2dFreeType::~GLFont2dFreeType()
00041 {
00042
00043
00044 FT_Done_Face(face_);
00045
00046
00047 FT_Done_FreeType(library_);
00048 }
00049
00050
00051 bool GLFont2dFreeType::createFont(const std::string &typeFace, unsigned int h, bool makeShadow)
00052 {
00053
00054 if (FT_Init_FreeType( &library_ ))
00055 {
00056 S3D::dialogMessage("GLFont2d", "FT_Init_FreeType failed");
00057 return false;
00058 }
00059
00060
00061
00062
00063 if (FT_New_Face( library_, typeFace.c_str(), 0, &face_ ))
00064 {
00065 S3D::dialogMessage("GLFont2d", S3D::formatStringBuffer(
00066 "FT_New_Face failed (there is probably a problem with your font file \"%s\")",
00067 typeFace.c_str()));
00068 return false;
00069 }
00070
00071
00072
00073
00074
00075 FT_Set_Char_Size( face_, h << 6, h << 6, 96, 96);
00076
00077 makeShadow_ = makeShadow;
00078
00079 return true;
00080 }
00081
00082 bool GLFont2dFreeType::createCharacter(unsigned int ch, GLFont2dStorage::CharEntry *character)
00083 {
00084
00085
00086
00087
00088 FT_UInt charIndex = FT_Get_Char_Index( face_, ch );
00089 if (!charIndex) {
00090 charIndex = FT_Get_Char_Index( face_, '?');
00091 }
00092
00093 if(FT_Load_Glyph( face_, charIndex, FT_LOAD_DEFAULT ))
00094 {
00095 S3D::dialogMessage("GLFont", "FT_Load_Glyph failed"); return false;
00096 }
00097
00098
00099 FT_Glyph glyph;
00100 if(FT_Get_Glyph( face_->glyph, &glyph ))
00101 {
00102 S3D::dialogMessage("GLFont", "FT_Get_Glyph failed"); return false;
00103 }
00104
00105
00106 FT_Glyph_To_Bitmap( &glyph, ft_render_mode_normal, 0, 1 );
00107 FT_BitmapGlyph bitmap_glyph = (FT_BitmapGlyph)glyph;
00108
00109
00110 FT_Bitmap& bitmap=bitmap_glyph->bitmap;
00111
00112
00113 int bitmap_width = bitmap.width;
00114 int bitmap_rows = bitmap.rows;
00115 unsigned char *bitmap_buffer = bitmap.buffer;
00116
00117 if (makeShadow_)
00118 {
00119 int shadow_width = bitmap_width + 4;
00120 int shadow_rows = bitmap_rows + 4;
00121 unsigned char *shadow_buffer = new unsigned char[
00122 shadow_width * shadow_rows];
00123 memset(shadow_buffer, 0, shadow_width * shadow_rows);
00124
00125 for(int j=2; j<shadow_rows-2;j++)
00126 {
00127 for(int i=2; i< shadow_width-2; i++)
00128 {
00129 int bi = i-2;
00130 int bj = j-2;
00131 unsigned char bitmapValue = bitmap_buffer[bi + bitmap_width*bj];
00132
00133 for (int b=-2; b<=2; b++)
00134 {
00135 for (int a=-2; a<=2; a++)
00136 {
00137 int si = i+a;
00138 int sj = j+b;
00139 unsigned char &shadowValue = shadow_buffer[si + shadow_width*sj];
00140
00141 int sv = int(shadowValue) + int(bitmapValue);
00142 if (sv > 255) sv = 255;
00143 shadowValue = (unsigned char) sv;
00144 }
00145 }
00146 }
00147 }
00148
00149 bitmap_width = shadow_width;
00150 bitmap_rows = shadow_rows;
00151 bitmap_buffer = shadow_buffer;
00152 }
00153
00154
00155
00156
00157 int width = next_p2( bitmap_width );
00158 int height = next_p2( bitmap_rows );
00159
00160
00161 GLubyte* expanded_data = new GLubyte[ 2 * width * height];
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 for(int j=0; j <height;j++) {
00172 for(int i=0; i < width; i++){
00173 expanded_data[2*(i+j*width)]= expanded_data[2*(i+j*width)+1] =
00174 (i>=bitmap_width || j>=bitmap_rows) ?
00175 0 : bitmap_buffer[i + bitmap_width*j];
00176 }
00177 }
00178
00179 if (makeShadow_) delete [] bitmap_buffer;
00180
00181
00182 glGenTextures(1, &character->texture);
00183 glBindTexture( GL_TEXTURE_2D, character->texture);
00184 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00185 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
00186 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
00187 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
00188
00189
00190
00191
00192 glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
00193 GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, expanded_data );
00194
00195
00196 delete [] expanded_data;
00197
00198
00199 character->displaylist = glGenLists(1);
00200 glNewList(character->displaylist, GL_COMPILE);
00201 glBindTexture(GL_TEXTURE_2D, character->texture);
00202 glPushMatrix();
00203
00204
00205
00206
00207 glTranslatef((float) bitmap_glyph->left, 0.0f, 0.0f);
00208 character->left = bitmap_glyph->left;
00209
00210
00211
00212
00213 glTranslatef(0.0f,(float) bitmap_glyph->top-bitmap_rows,0.0f);
00214 character->rows = bitmap_glyph->top-bitmap_rows;
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 float x=(float)bitmap_width / (float)width;
00225 float y=(float)bitmap_rows / (float)height;
00226 character->x = x;
00227 character->y = y;
00228
00229
00230
00231
00232
00233
00234 character->width = (float)bitmap_width;
00235 character->height = (float)bitmap_rows;
00236
00237 glBegin(GL_QUADS);
00238 glTexCoord2f(0.0f,0.0f); glVertex2f(0.0f,(float)bitmap_rows);
00239 glTexCoord2f(0.0f,y); glVertex2f(0.0f,0.0f);
00240 glTexCoord2f(x,y); glVertex2f((float)bitmap_width,0.0f);
00241 glTexCoord2f(x,0.0f); glVertex2f((float)bitmap_width,(float)bitmap_rows);
00242 glEnd();
00243 glPopMatrix();
00244 glTranslatef((float)(face_->glyph->advance.x >> 6) ,0.0f ,0.0f);
00245
00246 character->advances = (face_->glyph->advance.x >> 6);
00247
00248
00249
00250
00251
00252
00253 glEndList();
00254 return true;
00255 }