# HG changeset patch # User Thinker K.F. Li # Date 1217659542 -28800 # Node ID 0f3baa488a625730205ebfbbe4f1ebe08c347b6a # Parent 41f0907b27acde9f9c7266fa207627fbbebf32e6 Support solid color paint for fill. diff -r 41f0907b27ac -r 0f3baa488a62 src/Makefile --- a/src/Makefile Fri Aug 01 23:32:22 2008 +0800 +++ b/src/Makefile Sat Aug 02 14:45:42 2008 +0800 @@ -1,4 +1,4 @@ -SRCS = coord.c geo.c shape_path.c redraw_man.c tools.c +SRCS = coord.c geo.c shape_path.c redraw_man.c paint.c tools.c OBJS = ${SRCS:C/(.*)\.c/\1.o/g} TESTCASE_OBJS = ${SRCS:C/(.*)\.c/testcase-\1.o/g} CFLAGS+= -Wall -I/usr/local/include `pkg-config --cflags cairo` @@ -29,3 +29,6 @@ echo "delete $$i"; \ rm -f $$i; \ done + +depend: + mkdep $(CFLAGS) $(SRCS) diff -r 41f0907b27ac -r 0f3baa488a62 src/X_main.c --- a/src/X_main.c Fri Aug 01 23:32:22 2008 +0800 +++ b/src/X_main.c Sat Aug 02 14:45:42 2008 +0800 @@ -8,6 +8,7 @@ #include #include "shapes.h" #include "redraw_man.h" +#include "paint.h" Display *display; @@ -15,12 +16,15 @@ redraw_man_t rdman; shape_t *path; coord_t *coord; + paint_t *fill; int i; redraw_man_init(&rdman, cr); coord = rdman.root_coord; + fill = paint_color_new(&rdman, 1, 1, 0); path = sh_path_new("M 22,89.36218 C -34,-0.63782 39,-9.637817 82,12.36218 C 125,34.36218 142,136.36218 142,136.36218 C 100.66667,125.36218 74.26756,123.42795 22,89.36218 z "); + rdman_paint_fill(&rdman, fill, path); coord->matrix[0] = 0.8; coord->matrix[1] = 0; coord->matrix[2] = 20; @@ -33,15 +37,25 @@ XFlush(display); - for(i = 0; i < 10; i++) { - usleep(50000); - coord->matrix[2] += 5; - coord->matrix[5] += 5; + for(i = 0; i < 50; i++) { + usleep(20000); + coord->matrix[2] += 1; + coord->matrix[5] += 1; + paint_color_set(fill, 1, 1, (i/25) & 0x1); rdman_coord_changed(&rdman, coord); rdman_redraw_changed(&rdman); XFlush(display); } + for(i = 0; i < 5; i++) { + usleep(500000); + paint_color_set(fill, 1, i % 2, 0); + rdman_paint_changed(&rdman, fill); + rdman_redraw_changed(&rdman); + XFlush(display); + } + + fill->free(fill); redraw_man_destroy(&rdman); sh_path_free(path); } diff -r 41f0907b27ac -r 0f3baa488a62 src/geo.c --- a/src/geo.c Fri Aug 01 23:32:22 2008 +0800 +++ b/src/geo.c Sat Aug 02 14:45:42 2008 +0800 @@ -5,6 +5,7 @@ * figures out components that should be re-drawed. */ #include +#include #include "mb_types.h" static int is_scale_overlay(co_aix x1, co_aix w1, co_aix x2, co_aix w2) { diff -r 41f0907b27ac -r 0f3baa488a62 src/mb_types.h --- a/src/mb_types.h Fri Aug 01 23:32:22 2008 +0800 +++ b/src/mb_types.h Sat Aug 02 14:45:42 2008 +0800 @@ -1,12 +1,26 @@ #ifndef __MB_TYPES_H_ #define __MB_TYPES_H_ +#include #include "tools.h" typedef float co_aix; typedef struct _shape shape_t; typedef struct _geo geo_t; typedef struct _area area_t; +typedef struct _shnode shnode_t; +typedef struct _paint paint_t; + +struct _paint { + void (*prepare)(paint_t *paint, cairo_t *cr); + void (*free)(paint_t *paint); + STAILQ(shnode_t) members; +}; + +struct _shnode { + shape_t *shape; + shnode_t *next; +}; struct _area { co_aix x, y; @@ -96,6 +110,7 @@ geo_t *geo; coord_t *coord; shape_t *coord_mem_next; + paint_t *fill, *stroke; }; enum { SHT_UNKNOW, SHT_PATH, SHT_TEXT }; diff -r 41f0907b27ac -r 0f3baa488a62 src/paint.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/paint.c Sat Aug 02 14:45:42 2008 +0800 @@ -0,0 +1,50 @@ +#include +#include +#include +#include "paint.h" + +typedef struct _paint_color { + paint_t paint; + co_comp_t r, g, b; + redraw_man_t *rdman; +} paint_color_t; + + +static void paint_color_prepare(paint_t *paint, cairo_t *cr) { + paint_color_t *color = (paint_color_t *)paint; + + cairo_set_source_rgb(cr, color->r, color->g, color->b); +} + +static void paint_color_free(paint_t *paint) { + paint_color_t *color = (paint_color_t *)paint; + + shnode_list_free(color->rdman, paint->members); + free(paint); +} + +paint_t *paint_color_new(redraw_man_t *rdman, + co_comp_t r, co_comp_t g, co_comp_t b) { + paint_color_t *color; + + color = (paint_color_t *)malloc(sizeof(paint_color_t)); + if(color == NULL) + return NULL; + color->rdman = rdman; + color->r = r; + color->g = g; + color->b = b; + color->paint.prepare = paint_color_prepare; + color->paint.free = paint_color_free; + STAILQ_INIT(color->paint.members); + return (paint_t *)color; +} + +void paint_color_set(paint_t *paint, + co_comp_t r, co_comp_t g, co_comp_t b) { + paint_color_t *color = (paint_color_t *)paint; + + color->r = r; + color->g = g; + color->b = b; +} diff -r 41f0907b27ac -r 0f3baa488a62 src/paint.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/paint.h Sat Aug 02 14:45:42 2008 +0800 @@ -0,0 +1,15 @@ +#ifndef __PAINT_H_ +#define __PAINT_H_ + +#include +#include "mb_types.h" +#include "redraw_man.h" + +typedef float co_comp_t; + +extern paint_t *paint_color_new(redraw_man_t *rdman, + co_comp_t r, co_comp_t g, co_comp_t b); +extern void paint_color_set(paint_t *paint, + co_comp_t r, co_comp_t g, co_comp_t b); + +#endif /* __PAINT_H_ */ diff -r 41f0907b27ac -r 0f3baa488a62 src/redraw_man.c --- a/src/redraw_man.c Fri Aug 01 23:32:22 2008 +0800 +++ b/src/redraw_man.c Sat Aug 02 14:45:42 2008 +0800 @@ -196,6 +196,13 @@ return ERR; } + rdman->shnode_pool = elmpool_new(sizeof(shnode_t), 16); + if(rdman->shnode_pool == NULL) { + elmpool_free(rdman->geo_pool); + elmpool_free(rdman->coord_pool); + return ERR; + } + rdman->root_coord = elmpool_elm_alloc(rdman->coord_pool); if(rdman->root_coord == NULL) redraw_man_destroy(rdman); @@ -210,6 +217,7 @@ void redraw_man_destroy(redraw_man_t *rdman) { elmpool_free(rdman->coord_pool); elmpool_free(rdman->geo_pool); + elmpool_free(rdman->shnode_pool); if(rdman->dirty_coords) free(rdman->dirty_coords); if(rdman->dirty_geos) @@ -422,12 +430,7 @@ return OK; } -/*! \brief Mark a shape is changed. - * - * The geo_t object of a changed shape is mark as dirty and - * put into dirty_geos list. - */ -int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { +static int _rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { geo_t *geo; int r; @@ -444,11 +447,25 @@ return OK; } +/*! \brief Mark a shape is changed. + * + * The geo_t object of a changed shape is mark as dirty and + * put into dirty_geos list. + */ +int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape) { + return _rdman_shape_changed(rdman, shape); +} + /* Drawing and Redrawing * ============================================================ */ static void draw_shape(redraw_man_t *rdman, shape_t *shape) { + paint_t *fill; + + fill = shape->fill; + if(fill) + fill->prepare(fill, rdman->cr); switch(shape->sh_type) { case SHT_PATH: sh_path_draw(shape, rdman->cr); @@ -611,6 +628,31 @@ return OK; } +shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape) { + shnode_t *node; + + node = (shnode_t *)elmpool_elm_alloc(rdman->shnode_pool); + if(node) { + node->shape = shape; + node->next = NULL; + } + return node; +} + +int rdman_paint_changed(redraw_man_t *rdman, paint_t *paint) { + shnode_t *node; + int r; + + for(node = STAILQ_HEAD(paint->members); + node != NULL; + node = STAILQ_NEXT(shnode_t, next, node)) { + r = _rdman_shape_changed(rdman, node->shape); + if(r != OK) + return ERR; + } + return OK; +} + /* * Dirty of geo * A geo is dirty when any of the shape, size or positions is changed. diff -r 41f0907b27ac -r 0f3baa488a62 src/redraw_man.h --- a/src/redraw_man.h Fri Aug 01 23:32:22 2008 +0800 +++ b/src/redraw_man.h Sat Aug 02 14:45:42 2008 +0800 @@ -33,6 +33,7 @@ elmpool_t *geo_pool; elmpool_t *coord_pool; + elmpool_t *shnode_pool; int max_dirty_coords; int n_dirty_coords; @@ -63,6 +64,33 @@ extern int rdman_shape_changed(redraw_man_t *rdman, shape_t *shape); extern int rdman_redraw_changed(redraw_man_t *rdman); extern int rdman_redraw_all(redraw_man_t *rdman); +extern shnode_t *shnode_new(redraw_man_t *rdman, shape_t *shape); +#define shnode_free(rdman, node) elmpool_elm_free((rdman)->shnode_pool, node) +#define shnode_list_free(rdman, q) \ + do { \ + shnode_t *__node, *__last; \ + __last = STAILQ_HEAD(q); \ + if(__last == NULL) break; \ + for(__node = STAILQ_NEXT(shnode_t, next, __last); \ + __node != NULL; \ + __node = STAILQ_NEXT(shnode_t, next, __node)) { \ + shnode_free(rdman, __last); \ + __last = __node; \ + } \ + shnode_free(rdman, __last); \ + } while(0) +#define rdman_paint_fill(rdman, paint, shape) \ + do { \ + shnode_t *__node; \ + if((shape)->fill != (paint) && \ + (shape)->stroke != (paint)) { \ + __node = shnode_new(rdman, shape); \ + STAILQ_INS_TAIL((paint)->members, \ + shnode_t, next, __node); \ + } \ + shape->fill = paint; \ + } while(0) +extern int rdman_paint_changed(redraw_man_t *rdman, paint_t *paint); #endif /* __REDRAW_MAN_H_ */