added clipping rectangles
authorEleni Maria Stea <elene.mst@gmail.com>
Thu, 28 Feb 2013 01:42:19 +0000 (03:42 +0200)
committerEleni Maria Stea <elene.mst@gmail.com>
Thu, 28 Feb 2013 01:42:19 +0000 (03:42 +0200)
Makefile
src/fbdev/gfx.cc
src/gfx.cc [new file with mode: 0644]
src/gfx.h
src/main.cc
src/sdl/gfx.cc
src/text.cc
src/window.cc
src/wm.cc

index a132c3f..4242187 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -7,7 +7,7 @@ dbg = -g
 opt = -O0
 inc = -Isrc
 
-#backend = SDL
+backend = SDL
 
 ifeq ($(backend), SDL)
        def = -DWINNIE_SDL
index 742b6c6..422312c 100644 (file)
@@ -20,6 +20,7 @@ static unsigned char *framebuffer;
 static int dev_fd = -1;
 
 static Rect screen_rect;
+
 static int color_depth; // bits per pixel
 
 static Pixmap *pixmap;
@@ -47,6 +48,8 @@ bool init_gfx()
        screen_rect.height = sinfo.yres_virtual;
        color_depth = sinfo.bits_per_pixel;
 
+       set_clipping_rect(screen_rect);
+
        int sz = FRAMEBUFFER_SIZE(screen_rect.width, screen_rect.height, color_depth);
        framebuffer = (unsigned char*)mmap(0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, dev_fd, 0);
 
@@ -114,43 +117,6 @@ int get_color_depth()
        return color_depth;
 }
 
-void clear_screen(int r, int g, int b)
-{
-       fill_rect(screen_rect, r, g, b);
-}
-
-void fill_rect(const Rect &rect, int r, int g, int b)
-{
-       Rect drect = rect;
-
-       if(drect.x < screen_rect.x) {
-               drect.width -= screen_rect.x - drect.x;
-               drect.x = screen_rect.x;
-       }
-
-       if(drect.y < screen_rect.y) {
-               drect.height -= screen_rect.y - drect.y;
-               drect.y = screen_rect.y;
-       }
-
-       if(drect.x + drect.width >= screen_rect.x + screen_rect.width) {
-               drect.width = screen_rect.width - drect.x;
-       }
-
-       if(drect.y + drect.height >= screen_rect.y + screen_rect.height) {
-               drect.height = screen_rect.height - drect.y;
-       }
-
-       unsigned char *fb = framebuffer + (drect.x + screen_rect.width * drect.y) * 4;
-       for(int i=0; i<drect.height; i++) {
-               for(int j=0; j<drect.width; j++) {
-                       fb[j * 4] = b;
-                       fb[j * 4 + 1] = g;
-                       fb[j * 4 + 2] = r;
-               }
-               fb += screen_rect.width * 4;
-       }
-}
 
 void set_cursor_visibility(bool visible)
 {
@@ -162,101 +128,6 @@ void set_cursor_visibility(bool visible)
        }
 }
 
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
-               const Rect &dest_rect, int dest_x, int dest_y)
-{
-       int width = src_rect.width;
-       int height = src_rect.height;
-
-       int xoffs = dest_x - dest_rect.x;
-       if(xoffs < 0) {
-               dest_x = dest_rect.x;
-               width += xoffs;
-       }
-
-       int yoffs = dest_y - dest_rect.y;
-       if(yoffs < 0) {
-               dest_y = dest_rect.y;
-               height += yoffs;
-       }
-
-       int xend = dest_x + width;
-       if(xend >= dest_rect.width) {
-               width -= xend - dest_rect.width;
-       }
-
-       int yend = dest_y + height;
-       if(yend >= dest_rect.height) {
-               height -= yend - dest_rect.height;
-       }
-
-       if(width <= 0 || height <= 0) {
-               return;
-       }
-
-       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
-       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
-       for(int i=0; i<height; i++) {
-               memcpy(dptr, sptr, width * 4);
-               sptr += src_rect.width * 4;
-               dptr += dest_rect.width * 4;
-       }
-}
-
-void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
-               const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
-{
-       int width = src_rect.width;
-       int height = src_rect.height;
-
-       int xoffs = dest_x - dest_rect.x;
-       if(xoffs < 0) {
-               dest_x = dest_rect.x;
-               width += xoffs;
-       }
-
-       int yoffs = dest_y - dest_rect.y;
-       if(yoffs < 0) {
-               dest_y = dest_rect.y;
-               height += yoffs;
-       }
-
-       int xend = dest_x + width;
-       if(xend >= dest_rect.width) {
-               width -= xend - dest_rect.width;
-       }
-
-       int yend = dest_y + height;
-       if(yend >= dest_rect.height) {
-               height -= yend - dest_rect.height;
-       }
-
-       if(width <= 0 || height <= 0) {
-               return;
-       }
-
-       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
-       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
-       for(int i=0; i<height; i++) {
-               for(int j=0; j<width; j++) {
-                       int r = sptr[j * 4];
-                       int g = sptr[j * 4 + 1];
-                       int b = sptr[j * 4 + 2];
-
-                       if(r != key_r || g != key_g || b != key_b) {
-                               dptr[j * 4] = b;
-                               dptr[j * 4 + 1] = g;
-                               dptr[j * 4 + 2] = r;
-                       }
-               }
-
-               sptr += src_rect.width * 4;
-               dptr += dest_rect.width * 4;
-       }
-}
-
 void gfx_update()
 {
 }
diff --git a/src/gfx.cc b/src/gfx.cc
new file mode 100644 (file)
index 0000000..1da2953
--- /dev/null
@@ -0,0 +1,155 @@
+#include <string.h>
+
+#include "geom.h"
+#include "gfx.h"
+
+static Rect clipping_rect;
+
+void set_clipping_rect(const Rect &rect)
+{
+       clipping_rect = rect_intersection(rect, get_screen_size());
+}
+
+const Rect &get_clipping_rect()
+{
+       return clipping_rect;
+}
+
+void clear_screen(int r, int g, int b)
+{
+       Rect screen_rect = get_screen_size();
+       fill_rect(screen_rect, r, g, b);
+}
+
+void fill_rect(const Rect &rect, int r, int g, int b)
+{
+       Rect drect = rect;
+       Rect screen_rect = get_screen_size();
+
+       if(drect.x < clipping_rect.x) {
+               drect.width -= clipping_rect.x - drect.x;
+               drect.x = clipping_rect.x;
+       }
+
+       if(drect.y < clipping_rect.y) {
+               drect.height -= clipping_rect.y - drect.y;
+               drect.y = clipping_rect.y;
+       }
+
+       if(drect.x + drect.width >= clipping_rect.x + clipping_rect.width) {
+               drect.width = clipping_rect.width + clipping_rect.x - drect.x;
+       }
+
+       if(drect.y + drect.height >= clipping_rect.y + clipping_rect.height) {
+               drect.height = clipping_rect.height + clipping_rect.y - drect.y;
+       }
+
+       unsigned char *fb = get_framebuffer() + (drect.x + screen_rect.width * drect.y) * 4;
+       for(int i=0; i<drect.height; i++) {
+               for(int j=0; j<drect.width; j++) {
+                       fb[j * 4] = b;
+                       fb[j * 4 + 1] = g;
+                       fb[j * 4 + 2] = r;
+               }
+               fb += screen_rect.width * 4;
+       }
+}
+
+void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y)
+{
+       Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
+
+       int width = src_rect.width;
+       int height = src_rect.height;
+
+       int xoffs = dest_x - irect.x;
+       if(xoffs < 0) {
+               dest_x = irect.x;
+               width += xoffs;
+       }
+
+       int yoffs = dest_y - irect.y;
+       if(yoffs < 0) {
+               dest_y = irect.y;
+               height += yoffs;
+       }
+
+       int xend = dest_x + width;
+       if(xend >= irect.width) {
+               width -= xend - irect.width;
+       }
+
+       int yend = dest_y + height;
+       if(yend >= irect.height) {
+               height -= yend - irect.height;
+       }
+
+       if(width <= 0 || height <= 0) {
+               return;
+       }
+
+       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+       for(int i=0; i<height; i++) {
+               memcpy(dptr, sptr, width * 4);
+               sptr += src_rect.width * 4;
+               dptr += dest_rect.width * 4;
+       }
+}
+
+void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
+               const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
+{
+       Rect irect = rect_intersection(get_clipping_rect(), dest_rect);
+
+       int width = src_rect.width;
+       int height = src_rect.height;
+
+       int xoffs = dest_x - irect.x;
+       if(xoffs < 0) {
+               dest_x = irect.x;
+               width += xoffs;
+       }
+
+       int yoffs = dest_y - irect.y;
+       if(yoffs < 0) {
+               dest_y = irect.y;
+               height += yoffs;
+       }
+
+       int xend = dest_x + width;
+       if(xend >= irect.width) {
+               width -= xend - irect.width;
+       }
+
+       int yend = dest_y + height;
+       if(yend >= irect.height) {
+               height -= yend - irect.height;
+       }
+
+       if(width <= 0 || height <= 0) {
+               return;
+       }
+
+       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
+       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
+
+       for(int i=0; i<height; i++) {
+               for(int j=0; j<width; j++) {
+                       int r = sptr[j * 4];
+                       int g = sptr[j * 4 + 1];
+                       int b = sptr[j * 4 + 2];
+
+                       if(r != key_r || g != key_g || b != key_b) {
+                               dptr[j * 4] = r;
+                               dptr[j * 4 + 1] = g;
+                               dptr[j * 4 + 2] = b;
+                       }
+               }
+
+               sptr += src_rect.width * 4;
+               dptr += dest_rect.width * 4;
+       }
+}
index fb04e3b..76cb08a 100644 (file)
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -13,6 +13,9 @@ Pixmap *get_framebuffer_pixmap();
 Rect get_screen_size();
 int get_color_depth();
 
+void set_clipping_rect(const Rect &clip_rect);
+const Rect &get_clipping_rect();
+
 void clear_screen(int r, int g, int b);
 void fill_rect(const Rect &rect, int r, int g, int b);
 
index 054b922..46a412b 100644 (file)
@@ -19,7 +19,7 @@ int main()
        atexit(cleanup);
 
        Window *win1 = new Window;
-       win1->set_title("red");
+       win1->set_title("red klqljljljljljjkaHDJKAHKSHDjkahHSKHDKJSHKAHSJKHAKSHCJHSKFHJKSDHJKSHDJKH");
        win1->move(200, 100);
        win1->resize(200, 300);
        win1->set_display_callback(display);
@@ -46,17 +46,7 @@ int main()
 
 static void display(Window *win)
 {
-       const char *win_title = win->get_title();
-       const char *t1 = "red";
-       const char *t2 = "yellow";
-
-       if(!strcmp(win_title, t1)) {
-               fill_rect(win->get_absolute_rect(), 247, 68, 50);
-       }
-
-       if(!strcmp(win_title, t2)) {
-               fill_rect(win->get_absolute_rect(), 255, 215, 78);
-       }
+       fill_rect(win->get_absolute_rect(), 128, 128, 128);
 }
 
 static void keyboard(Window *win, int key, bool pressed)
index 1c4f347..84ab690 100644 (file)
@@ -7,6 +7,8 @@
 static SDL_Surface *fbsurf;
 
 static Rect screen_rect = {0, 0, 1024, 768};
+static Rect clipping_rect;
+
 static int color_depth = 32; // bits per pixel
 
 static Pixmap *pixmap;
@@ -29,6 +31,8 @@ bool init_gfx()
        pixmap->height = screen_rect.height;
        pixmap->pixels = (unsigned char*)fbsurf->pixels;
 
+       set_clipping_rect(screen_rect);
+
        return true;
 }
 
@@ -59,6 +63,24 @@ int get_color_depth()
        return color_depth;
 }
 
+/*void set_clipping_rect(const Rect &rect)
+{
+       clipping_rect = rect_intersection(rect, screen_rect);
+
+       SDL_Rect sdl_rect;
+       sdl_rect.x = clipping_rect.x;
+       sdl_rect.y = clipping_rect.y;
+       sdl_rect.w = clipping_rect.width;
+       sdl_rect.h = clipping_rect.height;
+
+       SDL_SetClipRect(fbsurf, &sdl_rect);
+}
+
+const Rect &get_clipping_rect()
+{
+       return clipping_rect;
+}
+
 void clear_screen(int r, int g, int b)
 {
        fill_rect(screen_rect, r, g, b);
@@ -75,107 +97,12 @@ void fill_rect(const Rect &rect, int r, int g, int b)
        sdl_rect.h = rect.height;
 
        SDL_FillRect(fbsurf, &sdl_rect, color);
-}
+}*/
 
 void set_cursor_visibility(bool visible)
 {
 }
 
-void blit(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
-               const Rect &dest_rect, int dest_x, int dest_y)
-{
-       int width = src_rect.width;
-       int height = src_rect.height;
-
-       int xoffs = dest_x - dest_rect.x;
-       if(xoffs < 0) {
-               dest_x = dest_rect.x;
-               width += xoffs;
-       }
-
-       int yoffs = dest_y - dest_rect.y;
-       if(yoffs < 0) {
-               dest_y = dest_rect.y;
-               height += yoffs;
-       }
-
-       int xend = dest_x + width;
-       if(xend >= dest_rect.width) {
-               width -= xend - dest_rect.width;
-       }
-
-       int yend = dest_y + height;
-       if(yend >= dest_rect.height) {
-               height -= yend - dest_rect.height;
-       }
-
-       if(width <= 0 || height <= 0) {
-               return;
-       }
-
-       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
-       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
-       for(int i=0; i<height; i++) {
-               memcpy(dptr, sptr, width * 4);
-               sptr += src_rect.width * 4;
-               dptr += dest_rect.width * 4;
-       }
-}
-
-void blit_key(unsigned char *src_img, const Rect &src_rect, unsigned char* dest_img,
-               const Rect &dest_rect, int dest_x, int dest_y, int key_r, int key_g, int key_b)
-{
-       int width = src_rect.width;
-       int height = src_rect.height;
-
-       int xoffs = dest_x - dest_rect.x;
-       if(xoffs < 0) {
-               dest_x = dest_rect.x;
-               width += xoffs;
-       }
-
-       int yoffs = dest_y - dest_rect.y;
-       if(yoffs < 0) {
-               dest_y = dest_rect.y;
-               height += yoffs;
-       }
-
-       int xend = dest_x + width;
-       if(xend >= dest_rect.width) {
-               width -= xend - dest_rect.width;
-       }
-
-       int yend = dest_y + height;
-       if(yend >= dest_rect.height) {
-               height -= yend - dest_rect.height;
-       }
-
-       if(width <= 0 || height <= 0) {
-               return;
-       }
-
-       unsigned char *sptr = src_img + (src_rect.y * src_rect.width + src_rect.x) * 4;
-       unsigned char *dptr = dest_img + (dest_y * dest_rect.width + dest_x) * 4;
-
-       for(int i=0; i<height; i++) {
-               for(int j=0; j<width; j++) {
-                       int r = sptr[j * 4];
-                       int g = sptr[j * 4 + 1];
-                       int b = sptr[j * 4 + 2];
-
-                       if(r != key_r || g != key_g || b != key_b) {
-                               dptr[j * 4] = r;
-                               dptr[j * 4 + 1] = g;
-                               dptr[j * 4 + 2] = b;
-                       }
-               }
-
-               sptr += src_rect.width * 4;
-               dptr += dest_rect.width * 4;
-       }
-}
-
 void gfx_update()
 {
        SDL_UpdateRect(fbsurf, 0, 0, 0, 0);
index 78bbcaf..ca0bf0b 100644 (file)
@@ -75,15 +75,31 @@ static int draw_glyph(Pixmap *pixmap, int x, int y, char c)
        unsigned char *bmp_ptr = ft_bmp->buffer;
        unsigned char *pxm_ptr = pixmap->get_image() + (pixmap->get_width() * y + x) * 4;
 
+       Rect clipping_rect = get_clipping_rect();
+
        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;
+               int dest_y = i + y;
+               if(dest_y >= clipping_rect.y + clipping_rect.height) {
+                       break;
+               }
+
+               if(dest_y >= clipping_rect.y) {
+                       for(int j=0; j<ft_bmp->width; j++) {
+                               int dest_x = j + x;
+
+                               if(dest_x >= clipping_rect.x + clipping_rect.width) {
+                                       break;
+                               }
+
+                               if(bmp_ptr[j] && dest_x >= clipping_rect.x) {
+                                       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;
        }
index 768c2ea..fb46b38 100644 (file)
@@ -96,14 +96,18 @@ void Window::draw(Rect *dirty_region)
        Rect abs_rect = get_absolute_rect();
        Rect intersect = rect_intersection(abs_rect, *dirty_region);
        if(intersect.width && intersect.height) {
+               Rect prev_clip = get_clipping_rect();
+               set_clipping_rect(abs_rect);
+               
                if(callbacks.display) {
                        callbacks.display(this);
                }
                dirty = false;
 
                draw_children(abs_rect);
-
+               
                *dirty_region = rect_union(*dirty_region, abs_rect);
+               set_clipping_rect(prev_clip);
        }
 }
 
index 7fe13fb..6652325 100644 (file)
--- a/src/wm.cc
+++ b/src/wm.cc
@@ -358,7 +358,6 @@ static void mouse(Window *win, int bn, bool pressed, int x, int y)
 static void motion(Window *win, int x, int y)
 {
        int left_bn = get_button(0);
-       int right_button = get_button(2);
 
        if(left_bn) {
                int dx = x - prev_x;