Mercurial > MadButterfly
changeset 55:01ed2bc37eed
Radial gradient paint
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sun, 10 Aug 2008 16:44:21 +0800 |
parents | 1b6dbafdf906 |
children | e444a8c01735 |
files | src/X_main.c src/paint.c src/paint.h src/tools.h |
diffstat | 4 files changed, 103 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/src/X_main.c Sun Aug 10 00:29:11 2008 +0800 +++ b/src/X_main.c Sun Aug 10 16:44:21 2008 +0800 @@ -127,6 +127,8 @@ shape_t *path1, *path2, *rect; coord_t *coord1, *coord2, *coord3; paint_t *fill1, *fill2, *fill3; + paint_t *text_fill; + grad_stop_t text_stops[2]; paint_t *stroke, *text_stroke; shape_t *text; grad_stop_t fill3_stops[3]; @@ -155,9 +157,12 @@ face = cairo_get_font_face(tmpcr); text = sh_text_new("hello \xe6\xbc\xa2\xe5\xad\x97", 10, h / 4, 36.0, face); + grad_stop_init(text_stops, 0, 0.2, 0.9, 0.2, 1); + grad_stop_init(text_stops + 1, 1, 0.9, 0.2, 0.2, 0.1); + text_fill = paint_radial_new(&rdman, 100, h / 4, 70, 2, text_stops); rdman_paint_stroke(&rdman, text_stroke, text); text->stroke_width = 0.5; - rdman_paint_fill(&rdman, fill1, text); + rdman_paint_fill(&rdman, text_fill, text); rdman_add_shape(&rdman, text, coord3); path1 = 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 "); @@ -237,6 +242,7 @@ fill2->free(fill2); stroke->free(stroke); text_stroke->free(text_stroke); + text_fill->free(text_fill); redraw_man_destroy(&rdman); sh_path_free(path1); sh_path_free(path2);
--- a/src/paint.c Sun Aug 10 00:29:11 2008 +0800 +++ b/src/paint.c Sun Aug 10 16:44:21 2008 +0800 @@ -3,6 +3,8 @@ #include <cairo.h> #include "paint.h" +#define ASSERT(x) + /*! \brief Solid color paint. */ typedef struct _paint_color { @@ -142,6 +144,90 @@ old_stops = linear->stops; linear->n_stops = n_stops; linear->stops = stops; + linear->flags |= LIF_DIRTY; + return old_stops; } +/*! \brief Radial gradient. + * + * NOTE: The only supported gradient unit is userSpaceOnUse. + */ +typedef struct _paint_radial { + paint_t paint; + co_aix cx, cy; + co_aix r; + int n_stops; + grad_stop_t *stops; + int flags; + cairo_pattern_t *ptn; +} paint_radial_t; + +#define RDF_DIRTY 0x1 + +static void paint_radial_prepare(paint_t *paint, cairo_t *cr) { + paint_radial_t *radial = (paint_radial_t *)paint; + cairo_pattern_t *ptn; + grad_stop_t *stop; + int i; + + if(radial->flags & RDF_DIRTY) { + ptn = cairo_pattern_create_radial(radial->cx, radial->cy, 0, + radial->cx, radial->cy, + radial->r); + ASSERT(ptn != NULL); + stop = radial->stops; + for(i = 0; i < radial->n_stops; i++, stop++) { + cairo_pattern_add_color_stop_rgba(ptn, stop->offset, + stop->r, stop->g, + stop->b, stop->a); + } + cairo_pattern_destroy(radial->ptn); + radial->ptn = ptn; + } + cairo_set_source(cr, radial->ptn); +} + +static void paint_radial_free(paint_t *paint) { + paint_radial_t *radial = (paint_radial_t *)paint; + + if(radial->ptn) + cairo_pattern_destroy(radial->ptn); + free(paint); +} + +paint_t *paint_radial_new(redraw_man_t *rdman, + co_aix cx, co_aix cy, co_aix r, + int n_stops, grad_stop_t *stops) { + paint_radial_t *radial; + + radial = O_ALLOC(paint_radial_t); + if(radial == NULL) + return NULL; + + paint_init(&radial->paint, paint_radial_prepare, paint_radial_free); + radial->cx = cx; + radial->cy = cy; + radial->r = r; + radial->n_stops = n_stops; + radial->stops = stops; + radial->flags = RDF_DIRTY; + radial->ptn = NULL; + + return (paint_t *)radial; +} + +grad_stop_t *paint_radial_stops(paint_t *paint, + int n_stops, + grad_stop_t *stops) { + paint_radial_t *radial = (paint_radial_t *)paint; + grad_stop_t *old_stops; + + old_stops = radial->stops; + radial->n_stops = n_stops; + radial->stops = stops; + radial->flags |= RDF_DIRTY; + + return old_stops; +} +
--- a/src/paint.h Sun Aug 10 00:29:11 2008 +0800 +++ b/src/paint.h Sun Aug 10 16:44:21 2008 +0800 @@ -35,6 +35,13 @@ extern grad_stop_t *paint_linear_stops(paint_t *paint, int n_stops, grad_stop_t *stops); +extern paint_t *paint_radial_new(redraw_man_t *rdman, + co_aix cx, co_aix cy, co_aix r, + int n_stops, grad_stop_t *stops); +extern grad_stop_t *paint_radial_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; \