added fonts - works with sdl version
[winnie] / src / text.cc
1 #include <ft2build.h>
2 #include <freetype/freetype.h>
3
4 #include "gfx.h"
5 #include "text.h"
6
7 #define DPI 72
8 #define FONT_PATH "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf"
9 #define FONT_SIZE 16
10
11 static int draw_glyph(Pixmap *pixmap, int x, int y, char c);
12
13 static FT_Library ft_lib;
14 static FT_Face ft_face;
15
16 static int text_x, text_y;
17 static int text_color[3] = {255, 255, 255};
18
19 bool init_text()
20 {
21         if(FT_Init_FreeType(&ft_lib)) {
22                 fprintf(stderr, "Failed to initialize the FreeType library!\n");
23                 return false;
24         }
25
26         if(FT_New_Face(ft_lib, FONT_PATH, 0, &ft_face)) {
27                 fprintf(stderr, "Failed to load font: %s\n", FONT_PATH);
28                 return false;
29         }
30
31         if(FT_Set_Char_Size(ft_face, 0, FONT_SIZE * 64, DPI, DPI)) {
32                 fprintf(stderr, "Failed to set font size\n");
33                 return false;
34         }
35
36         return true;
37 }
38
39 void draw_text(const char *txt, Pixmap *pixmap)
40 {
41         if(!pixmap) {
42                 pixmap = get_framebuffer_pixmap();
43         }
44
45         while(*txt != 0) {
46                 text_x += draw_glyph(pixmap, text_x, text_y, *txt);
47                 txt++;
48         }
49 }
50
51 void set_text_position(int x, int y)
52 {
53         text_x = x;
54         text_y = y;
55
56 }
57
58 void set_text_color(int r, int g, int b)
59 {
60         text_color[0] = r;
61         text_color[1] = g;
62         text_color[2] = b;
63 }
64
65 static int draw_glyph(Pixmap *pixmap, int x, int y, char c)
66 {
67         if(FT_Load_Char(ft_face, c, FT_LOAD_RENDER)) {
68                 return 0;
69         }
70
71         x += ft_face->glyph->bitmap_left;
72         y -= ft_face->glyph->bitmap_top;
73
74         FT_Bitmap *ft_bmp = &ft_face->glyph->bitmap;
75         unsigned char *bmp_ptr = ft_bmp->buffer;
76         unsigned char *pxm_ptr = pixmap->get_image() + (pixmap->get_width() * y + x) * 4;
77
78         for(int i=0; i<ft_bmp->rows; i++) {
79                 for(int j=0; j<ft_bmp->width; j++) {
80                         if(bmp_ptr[j]) {
81                                 int a = (int)bmp_ptr[j];
82                                 pxm_ptr[4 * j] = (a * text_color[0] + pxm_ptr[4 * j] * (255 - a)) / 255;
83                                 pxm_ptr[4 * j + 1] = (a * text_color[1] + pxm_ptr[4 * j + 1] * (255 - a)) / 255;
84                                 pxm_ptr[4 * j + 2] = (a * text_color[2] + pxm_ptr[4 * j + 2] * (255 - a)) / 255;
85                         }
86                 }
87                 pxm_ptr += 4 * pixmap->get_width();
88                 bmp_ptr += ft_bmp->pitch;
89         }
90
91         return ft_face->glyph->advance.x >> 6;
92 }