added fonts - works with sdl version
authorEleni Maria Stea <elene.mst@gmail.com>
Wed, 27 Feb 2013 01:51:43 +0000 (03:51 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Wed, 27 Feb 2013 01:51:43 +0000 (03:51 +0200)
todo: add fonts in the fb version too

src/gfx.h
src/main.cc
src/pixmap.h
src/sdl/gfx.cc
src/text.cc [new file with mode: 0644]
src/text.h [new file with mode: 0644]
src/winnie.cc
src/winnie.h
src/wm.cc
src/wm.h

index 2cf16b7..fb04e3b 100644 (file)
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -2,11 +2,14 @@
 #define GFX_H_
 
 #include "geom.h"
+#include "pixmap.h"
 
 bool init_gfx();
 void destroy_gfx();
 
 unsigned char *get_framebuffer();
+Pixmap *get_framebuffer_pixmap();
+
 Rect get_screen_size();
 int get_color_depth();
 
index cb6018d..054b922 100644 (file)
@@ -20,7 +20,7 @@ int main()
 
        Window *win1 = new Window;
        win1->set_title("red");
-       win1->move(5, 10);
+       win1->move(200, 100);
        win1->resize(200, 300);
        win1->set_display_callback(display);
        win1->set_keyboard_callback(keyboard);
@@ -29,7 +29,7 @@ int main()
 
        Window *win2 = new Window;
        win2->set_title("yellow");
-       win2->move(150, 10);
+       win2->move(300, 100);
        win2->resize(200, 300);
        win2->set_display_callback(display);
        win2->set_keyboard_callback(keyboard);
index 02a848b..9e5d5fb 100644 (file)
@@ -4,11 +4,10 @@
 #include "geom.h"
 
 class Pixmap {
-private:
+public:
        int width, height;
        unsigned char *pixels;
 
-public:
        Pixmap();
        ~Pixmap();
 
index 5be33e6..aec9663 100644 (file)
@@ -9,6 +9,8 @@ static SDL_Surface *fbsurf;
 static Rect screen_rect = {0, 0, 1024, 768};
 static int color_depth = 32; // bits per pixel
 
+static Pixmap *pixmap;
+
 bool init_gfx()
 {
        if(SDL_Init(SDL_INIT_VIDEO) == -1) {
@@ -22,11 +24,20 @@ bool init_gfx()
        }
        SDL_ShowCursor(0);
 
+       pixmap = new Pixmap;
+
+       pixmap->width = screen_rect.width;
+       pixmap->height = screen_rect.height;
+
+       pixmap->pixels = (unsigned char*)fbsurf->pixels;
+
        return true;
 }
 
 void destroy_gfx()
 {
+       pixmap->pixels = 0;
+       delete pixmap;
        SDL_Quit();
 }
 
@@ -35,6 +46,11 @@ unsigned char *get_framebuffer()
        return (unsigned char*)fbsurf->pixels;
 }
 
+Pixmap *get_framebuffer_pixmap()
+{
+       return pixmap;
+}
+
 Rect get_screen_size()
 {
        return screen_rect;
diff --git a/src/text.cc b/src/text.cc
new file mode 100644 (file)
index 0000000..78bbcaf
--- /dev/null
@@ -0,0 +1,92 @@
+#include <ft2build.h>
+#include <freetype/freetype.h>
+
+#include "gfx.h"
+#include "text.h"
+
+#define DPI 72
+#define FONT_PATH "/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf"
+#define FONT_SIZE 16
+
+static int draw_glyph(Pixmap *pixmap, int x, int y, char c);
+
+static FT_Library ft_lib;
+static FT_Face ft_face;
+
+static int text_x, text_y;
+static int text_color[3] = {255, 255, 255};
+
+bool init_text()
+{
+       if(FT_Init_FreeType(&ft_lib)) {
+               fprintf(stderr, "Failed to initialize the FreeType library!\n");
+               return false;
+       }
+
+       if(FT_New_Face(ft_lib, FONT_PATH, 0, &ft_face)) {
+               fprintf(stderr, "Failed to load font: %s\n", FONT_PATH);
+               return false;
+       }
+
+       if(FT_Set_Char_Size(ft_face, 0, FONT_SIZE * 64, DPI, DPI)) {
+               fprintf(stderr, "Failed to set font size\n");
+               return false;
+       }
+
+       return true;
+}
+
+void draw_text(const char *txt, Pixmap *pixmap)
+{
+       if(!pixmap) {
+               pixmap = get_framebuffer_pixmap();
+       }
+
+       while(*txt != 0) {
+               text_x += draw_glyph(pixmap, text_x, text_y, *txt);
+               txt++;
+       }
+}
+
+void set_text_position(int x, int y)
+{
+       text_x = x;
+       text_y = y;
+
+}
+
+void set_text_color(int r, int g, int b)
+{
+       text_color[0] = r;
+       text_color[1] = g;
+       text_color[2] = b;
+}
+
+static int draw_glyph(Pixmap *pixmap, int x, int y, char c)
+{
+       if(FT_Load_Char(ft_face, c, FT_LOAD_RENDER)) {
+               return 0;
+       }
+
+       x += ft_face->glyph->bitmap_left;
+       y -= ft_face->glyph->bitmap_top;
+
+       FT_Bitmap *ft_bmp = &ft_face->glyph->bitmap;
+       unsigned char *bmp_ptr = ft_bmp->buffer;
+       unsigned char *pxm_ptr = pixmap->get_image() + (pixmap->get_width() * y + x) * 4;
+
+       for(int i=0; i<ft_bmp->rows; i++) {
+               for(int j=0; j<ft_bmp->width; j++) {
+                       if(bmp_ptr[j]) {
+                               int a = (int)bmp_ptr[j];
+                               pxm_ptr[4 * j] = (a * text_color[0] + pxm_ptr[4 * j] * (255 - a)) / 255;
+                               pxm_ptr[4 * j + 1] = (a * text_color[1] + pxm_ptr[4 * j + 1] * (255 - a)) / 255;
+                               pxm_ptr[4 * j + 2] = (a * text_color[2] + pxm_ptr[4 * j + 2] * (255 - a)) / 255;
+                       }
+               }
+               pxm_ptr += 4 * pixmap->get_width();
+               bmp_ptr += ft_bmp->pitch;
+       }
+
+       return ft_face->glyph->advance.x >> 6;
+}
diff --git a/src/text.h b/src/text.h
new file mode 100644 (file)
index 0000000..55869e0
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef TEXT_H_
+#define TEXT_H_
+
+bool init_text();
+
+void draw_text(const char *txt, Pixmap *pixmap = 0);
+void set_text_position(int x, int y);
+void set_text_color(int r, int g, int b);
+
+#endif // TEXT_H_
index 4ec10b1..25d2ae3 100644 (file)
@@ -16,6 +16,10 @@ bool winnie_init()
                return false;
        }
 
+       if(!init_text()) {
+               return false;
+       }
+
        wm->invalidate_region(get_screen_size());
        return true;
 }
index 1abf460..6c495af 100644 (file)
@@ -4,6 +4,7 @@
 #include "event.h"
 #include "geom.h"
 #include "gfx.h"
+#include "text.h"
 #include "window.h"
 #include "wm.h"
 
index 056c6e7..7fe13fb 100644 (file)
--- a/src/wm.cc
+++ b/src/wm.cc
@@ -3,10 +3,11 @@
 #include <stdio.h>     // TODO
 
 #include "gfx.h"
-#include "wm.h"
-#include "window.h"
 #include "mouse.h"
 #include "mouse_cursor.h"
+#include "text.h"
+#include "wm.h"
+#include "window.h"
 
 WindowManager *wm;
 static WindowManager wminst;
@@ -80,8 +81,8 @@ WindowManager::WindowManager()
        frame_thickness = 8;
        titlebar_thickness = 16;
 
-       frame_fcolor[0] = frame_fcolor[1] = frame_fcolor[2] = 0;
-       frame_ucolor[0] = frame_ucolor[1] = frame_ucolor[2] = 255;
+       set_focused_frame_color(36, 59, 98);
+       set_unfocused_frame_color(80, 129, 162);
 
        mouse_cursor.set_image(mouse_cursor_width, mouse_cursor_height);
        unsigned char *pixels = mouse_cursor.get_image();
@@ -244,7 +245,7 @@ void WindowManager::set_focused_frame_color(int r, int g, int b)
        frame_fcolor[2] = b;
 }
 
-void WindowManager::get_focused_frame_color(int *r, int *g, int *b)
+void WindowManager::get_focused_frame_color(int *r, int *g, int *b) const
 {
        *r = frame_fcolor[0];
        *g = frame_fcolor[1];
@@ -258,6 +259,13 @@ void WindowManager::set_unfocused_frame_color(int r, int g, int b)
        frame_ucolor[2] = b;
 }
 
+void WindowManager::get_unfocused_frame_color(int *r, int *g, int *b) const
+{
+       *r = frame_ucolor[0];
+       *g = frame_ucolor[1];
+       *b = frame_ucolor[2];
+}
+
 Window *WindowManager::get_grab_window() const
 {
        return grab_win;
@@ -310,17 +318,24 @@ void WindowManager::sink_window(Window *win)
 static void display(Window *win)
 {
        //frame display:
-       Window **children = win->get_children();
-       for(int i=0; i<win->get_children_count(); i++) {
-               if(children[0] == wm->get_focused_window()) {
-                       int r, g, b;
-                       wm->get_focused_frame_color(&r, &g, &b);
-                       fill_rect(win->get_absolute_rect(), r, g, b);
-                       return;
-               }
+       Window *child = win->get_children()[0];
+       int r, g, b;
+       Rect abs_rect = win->get_absolute_rect();
+
+       //TODO 5 not hardcoded
+       set_text_position(abs_rect.x + 5, abs_rect.y + 15);
+       set_text_color(255, 255, 255);
+
+       if(child == wm->get_focused_window()) {
+               wm->get_focused_frame_color(&r, &g, &b);
+               fill_rect(abs_rect, r, g, b);
+       }
+       else {
+               wm->get_unfocused_frame_color(&r, &g, &b);
+               fill_rect(win->get_absolute_rect(), r, g, b);
        }
 
-       fill_rect(win->get_absolute_rect(), 74, 175, 198);
+       draw_text(child->get_title());
 }
 
 static int prev_x, prev_y;
index 7e677c2..b73a250 100644 (file)
--- a/src/wm.h
+++ b/src/wm.h
@@ -47,9 +47,10 @@ public:
        Window *get_root_window() const;
 
        void set_focused_frame_color(int r, int g, int b);
-       void get_focused_frame_color(int *r, int *g, int *b);
+       void get_focused_frame_color(int *r, int *g, int *b) const;
 
        void set_unfocused_frame_color(int r, int g, int b);
+       void get_unfocused_frame_color(int *r, int *g, int *b) const;
 
        Window *get_grab_window() const;