From 59cd3a77c4517e387f4c2e21e8b62a9017370116 Mon Sep 17 00:00:00 2001 From: Eleni Maria Stea Date: Thu, 28 Feb 2013 03:42:19 +0200 Subject: [PATCH] added clipping rectangles --- Makefile | 2 +- src/fbdev/gfx.cc | 135 ++--------------------------------------------- src/gfx.cc | 155 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/gfx.h | 3 ++ src/main.cc | 14 +---- src/sdl/gfx.cc | 119 ++++++++--------------------------------- src/text.cc | 28 +++++++--- src/window.cc | 6 ++- src/wm.cc | 1 - 9 files changed, 214 insertions(+), 249 deletions(-) create mode 100644 src/gfx.cc diff --git a/Makefile b/Makefile index a132c3f..4242187 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ dbg = -g opt = -O0 inc = -Isrc -#backend = SDL +backend = SDL ifeq ($(backend), SDL) def = -DWINNIE_SDL diff --git a/src/fbdev/gfx.cc b/src/fbdev/gfx.cc index 742b6c6..422312c 100644 --- a/src/fbdev/gfx.cc +++ b/src/fbdev/gfx.cc @@ -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= 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= 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 + +#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= 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= 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; iset_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) diff --git a/src/sdl/gfx.cc b/src/sdl/gfx.cc index 1c4f347..84ab690 100644 --- a/src/sdl/gfx.cc +++ b/src/sdl/gfx.cc @@ -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= 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; ibuffer; unsigned char *pxm_ptr = pixmap->get_image() + (pixmap->get_width() * y + x) * 4; + Rect clipping_rect = get_clipping_rect(); + for(int i=0; irows; i++) { - for(int j=0; jwidth; 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; jwidth; 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; } diff --git a/src/window.cc b/src/window.cc index 768c2ea..fb46b38 100644 --- a/src/window.cc +++ b/src/window.cc @@ -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); } } diff --git a/src/wm.cc b/src/wm.cc index 7fe13fb..6652325 100644 --- 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; -- 1.7.10.4