1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
void TTFFont::open(Bitmap& _bitmap,const char* _filename, unsigned int _size,Color _color,uint _charsperwidth,uint _charsperheight){
FT_Face face;
if(FT_New_Face(TTFFont::library.getLibrary(), _filename, 0, &face) != 0){
LogError error;
char buffer[1024];
sprintf(buffer,"Could not load font file: %s \n",_filename);
error.setError(buffer);
throw error;
}
if(!(face->face_flags & FT_FACE_FLAG_SCALABLE) ||
!(face->face_flags & FT_FACE_FLAG_HORIZONTAL)){
LogError error;
char buffer[1024];
sprintf(buffer,"Invalid font: Error setting font size: %s \n",_filename);
error.setError(buffer);
throw error;
}
FT_Set_Pixel_Sizes(face, _size, 0);
uint charWidth = 0;
uint charIndex = 0;
// widths.size() == 256
for(size_t ch = 0; ch < this->widths.size(); ++ch){
charIndex = FT_Get_Char_Index(face, ch);
FT_Load_Glyph(face, charIndex, FT_LOAD_DEFAULT);
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
this->widths[ch] = face->glyph->bitmap.width;
this->height = std::max<uint>(face->glyph->bitmap.rows,this->height);
charWidth = std::max<uint>(this->widths[ch],charWidth);
}
_bitmap.NewBitmap(charWidth*_charsperwidth,this->height*_charsperheight);
uint x = std::max<uint>(charWidth/2-this->widths[0]/2,0);
uint y = 0;
for(uint ch = 0; ch < this->widths.size(); ++ch){
uint charIndex = FT_Get_Char_Index(face, ch);
FT_Load_Glyph(face, charIndex, FT_LOAD_DEFAULT);
FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
for(int row = 0; row < face->glyph->bitmap.rows; ++row){
for(int pixel = 0; pixel < face->glyph->bitmap.width; ++pixel){
if(face->glyph->bitmap.buffer[pixel + row * face->glyph->bitmap.width] > 0){
uint pxi = 4*(x + y * _bitmap.getWidth());
_bitmap.getPixels()[pxi] = _color.red;
_bitmap.getPixels()[pxi+1] = _color.blue;
_bitmap.getPixels()[pxi+2] = _color.green;
_bitmap.getPixels()[pxi+3] = face->glyph->bitmap.buffer[pixel + row * face->glyph->bitmap.pitch];
}
}
}
x += charWidth;
if(x > _bitmap.getWidth()){
x = std::max<uint>(charWidth/2-this->widths[ch]/2,0);
y += this->height;
}
if(y > _bitmap.getHeight())
break;
}
FT_Done_Face(face);
}
|