Mercurial > MadButterfly
changeset 23:56f592f56ff7
Fix bug and add linear gradient paint.
- fix the bug that forget to clear n_dirty_geos in rdman_redraw_all().
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sat, 02 Aug 2008 23:10:42 +0800 |
parents | 8fcf2d878ecd |
children | e598bc809c0f |
files | src/X_main.c src/paint.c src/paint.h src/redraw_man.c |
diffstat | 4 files changed, 119 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/src/X_main.c Sat Aug 02 16:20:15 2008 +0800 +++ b/src/X_main.c Sat Aug 02 23:10:42 2008 +0800 @@ -14,10 +14,11 @@ void draw_path(cairo_t *cr, int w, int h) { redraw_man_t rdman; - shape_t *path1, *path2; + shape_t *path1, *path2, *path3; coord_t *coord1, *coord2; - paint_t *fill1, *fill2; + paint_t *fill1, *fill2, *fill3; paint_t *stroke; + grad_stop_t fill3_stops[3]; int i; redraw_man_init(&rdman, cr); @@ -48,6 +49,16 @@ rdman_add_shape(&rdman, (shape_t *)path1, coord1); rdman_add_shape(&rdman, (shape_t *)path2, coord2); + + fill3 = paint_linear_new(&rdman, 50, 50, 150, 150); + grad_stop_init(fill3_stops, 0, 1, 0, 0, 0.5); + grad_stop_init(fill3_stops + 1, 0.5, 0, 1, 0, 0.5); + grad_stop_init(fill3_stops + 2, 1, 0, 0, 1, 0.5); + paint_linear_stops(fill3, 3, fill3_stops); + path3 = sh_path_new("M 50,50 L 50,150 L 150,150 L 150,50 z"); + rdman_paint_fill(&rdman, fill3, path3); + rdman_add_shape(&rdman, (shape_t *)path3, rdman.root_coord); + rdman_redraw_all(&rdman); XFlush(display);
--- a/src/paint.c Sat Aug 02 16:20:15 2008 +0800 +++ b/src/paint.c Sat Aug 02 23:10:42 2008 +0800 @@ -3,6 +3,8 @@ #include <cairo.h> #include "paint.h" +/*! \brief Solid color paint. + */ typedef struct _paint_color { paint_t paint; co_comp_t r, g, b, a; @@ -50,3 +52,85 @@ color->b = b; color->a = a; } + +/*! \brief Linear gradient. + */ +typedef struct _paint_linear { + paint_t paint; + co_aix x1, y1; + co_aix x2, y2; + int n_stops; + grad_stop_t *stops; + int flags; + cairo_pattern_t *ptn; +} paint_linear_t; + +#define LIF_DIRTY 0x1 + +static void paint_linear_prepare(paint_t *paint, cairo_t *cr) { + paint_linear_t *linear = (paint_linear_t *)paint; + cairo_pattern_t *ptn; + grad_stop_t *stop; + int i; + + ptn = linear->ptn; + if(linear->flags & LIF_DIRTY) { + if(ptn) + cairo_pattern_destroy(ptn); + linear->flags &= ~LIF_DIRTY; + ptn = cairo_pattern_create_linear(linear->x1, linear->y1, + linear->x2, linear->y2); + for(i = 0; i < linear->n_stops; i++) { + stop = &linear->stops[i]; + cairo_pattern_add_color_stop_rgba(ptn, stop->offset, + stop->r, stop->g, stop->b, + stop->a); + } + linear->ptn = ptn; + } + + cairo_set_source(cr, ptn); +} + +static void paint_linear_free(paint_t *paint) { + paint_linear_t *linear = (paint_linear_t *)paint; + + if(linear->ptn) + cairo_pattern_destroy(linear->ptn); + free(paint); +} + +paint_t *paint_linear_new(redraw_man_t *rdman, + co_aix x1, co_aix y1, co_aix x2, co_aix y2) { + paint_linear_t *linear; + + linear = (paint_linear_t *)malloc(sizeof(paint_linear_t)); + if(linear == NULL) + return NULL; + + paint_init(&linear->paint, paint_linear_prepare, paint_linear_free); + + linear->x1 = x1; + linear->y1 = y1; + linear->x2 = x2; + linear->y2 = y2; + linear->n_stops = 0; + linear->stops = NULL; + linear->flags = LIF_DIRTY; + linear->ptn = NULL; + + return (paint_t *)linear; +} + +grad_stop_t *paint_linear_stops(paint_t *paint, + int n_stops, + grad_stop_t *stops) { + paint_linear_t *linear = (paint_linear_t *)paint; + grad_stop_t *old_stops; + + old_stops = linear->stops; + linear->n_stops = n_stops; + linear->stops = stops; + return old_stops; +} +
--- a/src/paint.h Sat Aug 02 16:20:15 2008 +0800 +++ b/src/paint.h Sat Aug 02 23:10:42 2008 +0800 @@ -21,4 +21,25 @@ STAILQ_INIT((_paint)->members); \ } while(0) \ + +typedef struct _grad_stop { + co_aix offset; + co_comp_t r, g, b, a; +} grad_stop_t; + +extern paint_t *paint_linear_new(redraw_man_t *rdman, + co_aix x1, co_aix y1, co_aix x2, co_aix y2); +extern grad_stop_t *paint_linear_stops(paint_t *paint, + int n_stops, + grad_stop_t *stops); +#define grad_stop_init(stop, _offset, _r, _g, _b, _a) \ + do { \ + (stop)->offset = _offset; \ + (stop)->r = _r; \ + (stop)->g = _g; \ + (stop)->b = _b; \ + (stop)->a = _a; \ + } while(0) + + #endif /* __PAINT_H_ */