Index: proj/font/split_font.py
===================================================================
--- proj/font/split_font.py	(revision 182)
+++ proj/font/split_font.py	(revision 183)
@@ -11,36 +11,33 @@
 
 i = 32
 
-with open("font.h", 'w') as f:
-    includes = ""
-    lst = ""
+includes = ""
+lst = ""
 
-    for j in range(i):
-        if lst != "": lst += ","
-        lst += "NULL"
+for j in range(i):
+    if lst != "": lst += ","
+    lst += "NULL"
 
 
-    for h in range(Nh):
-        t = int(H/Nh)*h
-        b = int(H/Nh)*(h+1)
-        for w in range(Nw):
-            #l = int((W*w)/Nw)
-            #r = int((W*(w+1))/Nw)
-            l = 59*w
-            r = 59*(w+1)
-            im1 = im.crop((l,t,r,b))
-            im1.save("png/ascii%03d.png"%i)
-            os.system("convert png/ascii%03d.png xpm/ascii%03d.xpm"%(i,i))
+for h in range(Nh):
+    t = int(H/Nh)*h
+    b = int(H/Nh)*(h+1)
+    for w in range(Nw):
+        #l = int((W*w)/Nw)
+        #r = int((W*(w+1))/Nw)
+        l = 59*w
+        r = 59*(w+1)
+        im1 = im.crop((l,t,r,b))
+        im1.save("png/ascii%03d.png"%i)
+        os.system("convert png/ascii%03d.png xpm/ascii%03d.xpm"%(i,i))
+        
+        includes += '#include "%03d.xpm"\n'%i
+        if lst != "": lst += ","
+        lst += "%03d_xpm"%i
 
-            
-            includes += '#include "%03d.xpm"\n'%i
-            if lst != "": lst += ","
-            lst += "%03d_xpm"%i
+        #DEV
+        os.system("rm png/ascii%03d.png"%i)
 
-            #DEV
-            os.system("rm png/ascii%03d.png"%i)
+        i += 1
 
-            i += 1
-
-    f.write(includes)
-    f.write("xpm_map_t font[] = {"+lst+"}\n")
\ No newline at end of file
+os.system('sed -i "s/black/#000000/g" xpm/*.xpm')
Index: proj/include/font.h
===================================================================
--- proj/include/font.h	(revision 182)
+++ proj/include/font.h	(revision 183)
@@ -1,12 +1,19 @@
 #ifndef FONT_H_INCLUDED
 #define FONT_H_INCLUDED
 
-struct glyph;
-typedef struct glyph glyph_t;
+struct font;
+typedef struct font font_t;
+font_t* (font_ctor)(const char *s);
+void    (font_dtor)(font_t *p);
 
-glyph_t* (glyph_ctor)(const char **xpm);
-void     (glyph_dtor)(glyph_t *p);
+struct text;
+typedef struct text text_t;
+text_t* (text_ctor)(const font_t *fnt, const char *txt);
+void    (text_dtor)(text_t *p);
+void (text_set_text) (text_t *p, const char *txt);
+void (text_set_pos)  (text_t *p, int16_t x, int16_t y);
+void (text_set_size) (text_t *p, unsigned size);
+void (text_set_color)(text_t *p, uint32_t color);
+void (text_draw)     (const text_t *p);
 
-//glyph_t** (get_font)(const char *s);
-
 #endif //FONT_H_INCLUDED
Index: proj/include/graph.h
===================================================================
--- proj/include/graph.h	(revision 182)
+++ proj/include/graph.h	(revision 183)
@@ -1,12 +1,15 @@
 #ifndef GRAPH_H_INCLUDED
 #define GRAPH_H_INCLUDED
 
+#include "graph_macros.h"
+
 /// MACROS
-//#define GET_ALP(n)          (0xFF & ((n) >> 24))
+#define GET_ALP(n)          (0xFF & ((n) >> 24))
 #define GET_RED(n)          (0xFF & ((n) >> 16))
 #define GET_GRE(n)          (0xFF & ((n) >>  8))
 #define GET_BLU(n)          (0xFF & (n      ))
-//#define SET_ALP(n)          (((n)&0xFF) << 24)
+#define GET_COLOR(n)        (0xFFFFFF & (n))
+#define SET_ALP(n)          (((n)&0xFF) << 24)
 #define SET_RED(n)          (((n)&0xFF) << 16)
 #define SET_GRE(n)          (((n)&0xFF) <<  8)
 #define SET_BLU(n)          (((n)&0xFF)      )
@@ -23,8 +26,10 @@
 int (graph_cleanup)(void);
 
 /// PIXEL DRAWING
-int (graph_set_pixel)      (uint16_t x, uint16_t y, uint32_t color);
-int (graph_set_pixel_alpha)(uint16_t x, uint16_t y, uint32_t color, uint8_t alpha);
+int (graph_set_pixel)             (uint16_t x, uint16_t y, uint32_t color);
+int (graph_set_pixel_buffer)      (uint16_t x, uint16_t y, uint32_t color, uint8_t *buf, uint16_t W, uint16_t H);
+int (graph_set_pixel_alpha_buffer)(uint16_t x, uint16_t y, uint8_t alpha, uint8_t *alp_buf, uint16_t W, uint16_t H);
+int (graph_set_pixel_alpha)       (uint16_t x, uint16_t y, uint32_t color, uint8_t alpha);
 
 /// SCREEN
 int (graph_clear_screen)(void);
Index: proj/include/graph_macros.h
===================================================================
--- proj/include/graph_macros.h	(revision 182)
+++ proj/include/graph_macros.h	(revision 183)
@@ -28,5 +28,6 @@
 
 // Colors in RBG (8 bit)
 #define BLACK               0x000000
+#define WHITE               0xFFFFFF
 
 #endif /* end of include guard: GRAPHICS_MACROS_H_INCLUDED */
Index: proj/include/xpm_utils.h
===================================================================
--- proj/include/xpm_utils.h	(revision 182)
+++ proj/include/xpm_utils.h	(revision 183)
@@ -5,4 +5,4 @@
 
 char** xpm_load_xpm2(const char *s);
 
-#endif //XMP_UTILS_H_INCLUDED
\ No newline at end of file
+#endif //XMP_UTILS_H_INCLUDED
Index: proj/src/font.c
===================================================================
--- proj/src/font.c	(revision 182)
+++ proj/src/font.c	(revision 183)
@@ -2,12 +2,18 @@
 
 #include "font.h"
 
+#include "xpm_utils.h"
+#include "graph.h"
+#include "utils.h"
+#include "errors.h"
+
 struct glyph{
     uint16_t w, h;
     uint8_t *map;
 };
-
-glyph_t* (glyph_ctor)(const char **xpm){
+typedef struct glyph glyph_t;
+static glyph_t* (glyph_ctor)(const char **xpm){
+    if(xpm == NULL) return NULL;
     glyph_t *ret = malloc(sizeof(glyph_t));
     if(ret == NULL) return NULL;
     enum xpm_image_type type = XPM_8_8_8_8;
@@ -21,9 +27,146 @@
     ret->h = img.height;
     return ret;
 }
-
-void (glyph_dtor)(glyph_t *p){
+static void (glyph_dtor)(glyph_t *p){
     if(p == NULL) return;
     free(p->map);
     free(p);
 }
+static int (glyph_draw_to_alpha_buffer)(const glyph_t *p, int16_t x, int16_t y, uint8_t *alp_buf, uint16_t W, uint16_t H){
+    if(p == NULL) return NULL_PTR;
+    int r;
+    for(int16_t h = 0; h < p->h; ++h){
+        for(int16_t w = 0; w < p->w; ++w){
+            uint32_t c = *((uint32_t*)p->map + w + h*p->w);
+            uint8_t a = GET_ALP(c);
+            //c = c & 0xFF000000;
+            //if(c != 0) printf("%d %d 0x%X\n", w, h, c);
+            //else       printf("%d %d <========================\n");
+
+            r = graph_set_pixel_alpha_buffer(x+w, y-p->h+h, a, alp_buf, W, H);
+
+
+            //r = graph_set_pixel_alpha(x+w, y-p->h+h, GET_COLOR(c), GET_ALP(c));
+
+            //printf("%d %d 0x%X\n", x, y, *(buf+(x+y*p->w)*sizeof(uint32_t)));
+            if(r != SUCCESS && r != OUT_OF_RANGE) return r;
+        }
+    }
+    return SUCCESS;
+}
+
+struct font{
+    size_t nchars;
+    glyph_t **glyphs;
+};
+#include "sprite.h"
+#include "rectangle.h"
+font_t* (font_ctor)(const char *s){
+    font_t *ret = malloc(sizeof(font_t));
+    if(ret == NULL) return NULL;
+    ret->nchars = 128;
+    ret->glyphs = malloc(ret->nchars*sizeof(glyph_t*));
+    if(ret->glyphs == NULL){
+        free(ret->glyphs);
+        free(ret);
+        return NULL;
+    }
+    char filepath[1024];
+    for(size_t i = 0; i < ret->nchars; ++i){
+        sprintf(filepath, "%s/ascii%03d.xpm2", s, i);
+        char **xpm = xpm_load_xpm2(filepath);
+        ret->glyphs[i] = glyph_ctor((const char**)xpm);
+    }
+    return ret;
+}
+void (font_dtor)(font_t *p){
+    if(p == NULL) return;
+    for(size_t i = 0; i < p->nchars; ++i)
+        glyph_dtor(p->glyphs[i]);
+    free(p->glyphs);
+    free(p);
+}
+
+struct text{
+    const font_t *fnt;
+    char *txt;
+    int16_t x, y;
+    int size;
+    uint32_t color;
+};
+text_t* (text_ctor)(const font_t *fnt, const char *txt){
+    if(fnt == NULL) return NULL;
+    text_t *ret = malloc(sizeof(text_t));
+    if(ret == NULL) return NULL;
+    ret->fnt = fnt;
+    ret->txt = NULL;
+    text_set_text(ret, txt);
+    ret->x = 0;
+    ret->y = 0;
+    ret->size = 70;
+    ret->color = BLACK;
+    return ret;
+}
+void (text_dtor)(text_t *p){
+    if(p == NULL) return;
+    free(p->txt);
+    free(p);
+}
+void (text_set_text) (text_t *p, const char *txt){
+    size_t sz = strlen(txt);
+    p->txt = realloc(p->txt, (sz+1)*sizeof(char));
+    if(p->txt == NULL) return;
+    strcpy(p->txt, txt);
+}
+void (text_set_pos)  (text_t *p, int16_t x, int16_t y){ p->x = x; p->y = y; }
+void (text_set_size) (text_t *p, unsigned size       ){ p->size = size;     }
+void (text_set_color)(text_t *p, uint32_t color      ){ p->color = color;   }
+void (text_draw)(const text_t *p){
+    printf("-%s-\n", p->txt);
+    const size_t len = strlen(p->txt);
+    uint16_t W = 0, H = 0;
+    for(size_t i = 0; i < len; ++i){
+        const glyph_t *g = p->fnt->glyphs[(size_t)p->txt[i]];
+        if(g != NULL){ W += g->w; H = max(H, g->h); }
+    }
+    printf("%d %d\n", W, H);
+
+    uint8_t *alp_buf = malloc(W*H);
+
+    {
+        int16_t y = H;
+        int16_t x = 0;
+        for(size_t i = 0; i < len; ++i){
+            const glyph_t *g = p->fnt->glyphs[(size_t)p->txt[i]];
+            if(g != NULL){
+                if(glyph_draw_to_alpha_buffer(g, x, y, alp_buf, W, H)) return;
+                x += g->w;
+            }
+        }
+    }
+    double factor = (double)p->size/(double)H;
+
+    uint16_t newH = H*factor;
+    uint16_t newW = W*factor;
+
+    for(size_t newy = 0; newy < newH; ++newy){
+        size_t y = newy/factor;
+        for(size_t newx = 0; newx < newW; ++newx){
+            size_t x = newx/factor;
+            *(alp_buf+newx+newy*W) = *(alp_buf+x+y*W);
+            (void)x;
+            (void)y;
+        }
+    }
+
+    printf("L163\n");
+    for(int16_t y = 0; y < newH; ++y){ //printf("L163,%d\n", y);
+        for(int16_t x = 0; x < newW; ++x){ //if(y > 147) printf("L164, %d %d\n", x, y);
+            uint8_t a = *(alp_buf+x+y*W); //if(y > 147) printf("L165\n");
+            graph_set_pixel_alpha(x+p->x,y+p->y,p->color, a); //if(y > 147) printf("L166\n");
+        }
+    }
+    printf("L170\n");
+    free(alp_buf);
+    printf("L172\n");
+}
Index: proj/src/graph.c
===================================================================
--- proj/src/graph.c	(revision 182)
+++ proj/src/graph.c	(revision 183)
@@ -1,9 +1,8 @@
 #include <lcom/lcf.h>
 
 #include "graph.h"
-#include "graph_macros.h"
+
 #include "errors.h"
-
 #include <stdio.h>
 
 /// MACROS
@@ -245,7 +244,8 @@
 
 /// PIXEL DRAWING
 int (graph_set_pixel)(uint16_t x, uint16_t y, uint32_t color) {
-    if (x >= vbe_mem_info.XResolution || y >= vbe_mem_info.YResolution) {
+    /*
+    if (x < 0 || vbe_mem_info.XResolution <= x || y < 0 || vbe_mem_info.YResolution <= y) {
         //printf("%s: invalid pixel.\n", __func__);
         return OUT_OF_RANGE;
     }
@@ -252,12 +252,33 @@
     unsigned int pos = (x + y * vbe_mem_info.XResolution) * graph_get_bytes_pixel();
     memcpy(video_buf + pos, &color, graph_get_bytes_pixel());
     return SUCCESS;
+    */
+    return graph_set_pixel_buffer(x, y, color, video_buf, graph_get_XRes(), graph_get_YRes());
 }
+int (graph_set_pixel_buffer)(uint16_t x, uint16_t y, uint32_t color, uint8_t *buf, uint16_t W, uint16_t H) {
+    if (x < 0 || W <= x || y < 0 || H <= y) {
+        //printf("%s: invalid pixel.\n", __func__);
+        return OUT_OF_RANGE;
+    }
+    unsigned int pos = (x + y * W) * graph_get_bytes_pixel();
+    memcpy(buf + pos, &color, graph_get_bytes_pixel());
+    return SUCCESS;
+}
+int (graph_set_pixel_alpha_buffer)(uint16_t x, uint16_t y, uint8_t alpha, uint8_t *alp_buf, uint16_t W, uint16_t H) {
+    if (x < 0 || W <= x || y < 0 || H <= y) {
+        //printf("%s: invalid pixel.\n", __func__);
+        return OUT_OF_RANGE;
+    }
+    unsigned int pos = x + y * W;
+    memcpy(alp_buf + pos, &alpha, 1);
+    return SUCCESS;
+}
 int (graph_set_pixel_alpha)(uint16_t x, uint16_t y, uint32_t color, uint8_t alpha){
     if (x >= vbe_mem_info.XResolution || y >= vbe_mem_info.YResolution) {
         //printf("%s: invalid pixel.\n", __func__);
         return OUT_OF_RANGE;
     }
+    //printf("COLOR= %X, ALPHA = %X\n", color, alpha);
     unsigned int pos = (x + y * vbe_mem_info.XResolution) * graph_get_bytes_pixel();
     uint32_t color_;
     memcpy(&color_, video_buf + pos, graph_get_bytes_pixel());
Index: proj/src/proj.c
===================================================================
--- proj/src/proj.c	(revision 182)
+++ proj/src/proj.c	(revision 183)
@@ -16,6 +16,10 @@
 #include "rectangle.h"
 #include "font.h"
 
+#ifdef DIOGO
+    #include "shooter.h"
+#endif
+
 #ifdef TELMO
     #include "crosshair.h"
 #endif
@@ -53,11 +57,15 @@
         //printf("%d\n", 1000000-(int)(1000000*fm_sin(0.5*M_PI)));
         //printf("%d\n", (int)(1000000*fm_cos(0.5*M_PI)));
         /*
+        rectangle_t *rect = rectangle_ctor(0,0,graph_get_XRes(), graph_get_YRes());
+        rectangle_set_fill_color(rect, WHITE);
+
         clock_t t = clock();
         sprite_t *shooter1 = get_shooter(); sprite_set_pos(shooter1, 100, 100);
         for(double angle = 0; angle <= 6.283185; angle += 0.006283185){
              sprite_set_angle(shooter1, angle);
              graph_clear_screen();
+             rectangle_draw(rect);
              sprite_draw(shooter1);
              graph_draw();
         }
@@ -84,8 +92,26 @@
         graph_draw();
         */
 
+        font_t      *fnt  = font_ctor("/home/lcom/labs/proj/font/xpm2");
 
 
+        rectangle_t *rect = rectangle_ctor(100,100,100, 100);
+        rectangle_set_fill_color(rect, WHITE);
+        rectangle_draw(rect);
+        rectangle_dtor(rect);
+
+        text_t      *txt  = text_ctor(fnt, "Hello world!");
+        text_set_color(txt, 0x00FF00);
+        text_set_pos(txt, 100, 100);
+        text_draw(txt);
+        text_dtor(txt);
+
+        graph_draw();
+
+        font_dtor(fnt);
+
+        tickdelay(micros_to_ticks(1000000));
+
     #endif
 
     #ifdef TELMO
@@ -100,6 +126,10 @@
     message msg;
     int good = 1;
 
+    #ifdef DIOGO
+        good = 0;
+    #endif
+
     while (good) {
         /* Get a request message. */
         if ((r = driver_receive(ANY, &msg, &ipc_status)) != 0) {
Index: proj/src/sprite.c
===================================================================
--- proj/src/sprite.c	(revision 182)
+++ proj/src/sprite.c	(revision 183)
@@ -65,9 +65,8 @@
         for(int16_t x = max(0,p->x-diag); x < min(p->x+diag,graph_get_XRes()); ++x){
             sprite_src2pic(p, x, y, &u, &v);
             if(0 <= u && u < p->w && 0 <= v && v < p->h){
-                uint8_t *m = p->map + (v*p->w + u)*4;
-                uint32_t color = SET_RGB(*(m+2), *(m+1), *(m));
-                graph_set_pixel_alpha(p->x + x, p->y + y, color, *(m+3));
+                uint32_t c = *(uint32_t*)(p->map + (v*p->w + u)*4);
+                graph_set_pixel_alpha(p->x + x, p->y + y, GET_COLOR(c), GET_ALP(c));
             }
         }
     }
Index: proj/src/xpm_utils.c
===================================================================
--- proj/src/xpm_utils.c	(revision 182)
+++ proj/src/xpm_utils.c	(revision 183)
@@ -32,15 +32,20 @@
         sscanf(line_buf, "%d %d %d %d", &w, &h, &num_colors, &chars_per_pixel);
         ret = malloc((1+num_colors+h)*sizeof(char*));
     }
-    ret[0] = malloc((sz+1)*sizeof(char));
+    ret[0] = malloc((sz+1)*sizeof(char)); if(ret[0] == NULL){ free(ret); return NULL; }
     strcpy(ret[0], line_buf);
-    
+
     for(int i = 1; i < 1+num_colors+h; ++i){
         sz = getline(&line_buf, &len, f);
         ret[i] = malloc((sz+1)*sizeof(char));
+        if(ret[i] == NULL){
+            for(int j = 0; j < i; ++j)
+                free(ret[i]);
+            free(ret);
+            return NULL;
+        }
         strcpy(ret[i], line_buf);
         ret[i][sz-1] = '\0';
-        printf("%s\n", ret[i]);
     }
     fclose(f); f = NULL;
     return ret;
Index: proj/DR.mk
===================================================================
--- proj/DR.mk	(revision 182)
+++ proj/DR.mk	(revision 183)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D DIOGO -D __LCOM_OPTIMIZED_
 
Index: proj/Makefile
===================================================================
--- proj/Makefile	(revision 182)
+++ proj/Makefile	(revision 183)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D __LCOM_OPTIMIZED_
 
Index: proj/TB.mk
===================================================================
--- proj/TB.mk	(revision 182)
+++ proj/TB.mk	(revision 183)
@@ -2,7 +2,7 @@
 
 .PATH: ${.CURDIR}/src
 
-SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c
+SRCS= proj.c graph.c sprite.c kbc.c keyboard.c mouse.c utils.c timer.c interrupts_func.c proj_func.c fast_math.c rectangle.c font.c xpm_utils.c
 
 CPPFLAGS += -pedantic -I./include -I./bmp -I./xpm -D LCOM_MACRO -D TELMO #-D __LCOM_OPTIMIZED_
 
