Mercurial > MadButterfly
diff src/paint.c @ 55:01ed2bc37eed
Radial gradient paint
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Sun, 10 Aug 2008 16:44:21 +0800 |
parents | 59a295651480 |
children | e444a8c01735 |
line wrap: on
line diff
--- 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; +} +