comparison 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
comparison
equal deleted inserted replaced
54:1b6dbafdf906 55:01ed2bc37eed
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <cairo.h> 3 #include <cairo.h>
4 #include "paint.h" 4 #include "paint.h"
5
6 #define ASSERT(x)
5 7
6 /*! \brief Solid color paint. 8 /*! \brief Solid color paint.
7 */ 9 */
8 typedef struct _paint_color { 10 typedef struct _paint_color {
9 paint_t paint; 11 paint_t paint;
140 grad_stop_t *old_stops; 142 grad_stop_t *old_stops;
141 143
142 old_stops = linear->stops; 144 old_stops = linear->stops;
143 linear->n_stops = n_stops; 145 linear->n_stops = n_stops;
144 linear->stops = stops; 146 linear->stops = stops;
147 linear->flags |= LIF_DIRTY;
148
145 return old_stops; 149 return old_stops;
146 } 150 }
147 151
152 /*! \brief Radial gradient.
153 *
154 * NOTE: The only supported gradient unit is userSpaceOnUse.
155 */
156 typedef struct _paint_radial {
157 paint_t paint;
158 co_aix cx, cy;
159 co_aix r;
160 int n_stops;
161 grad_stop_t *stops;
162 int flags;
163 cairo_pattern_t *ptn;
164 } paint_radial_t;
165
166 #define RDF_DIRTY 0x1
167
168 static void paint_radial_prepare(paint_t *paint, cairo_t *cr) {
169 paint_radial_t *radial = (paint_radial_t *)paint;
170 cairo_pattern_t *ptn;
171 grad_stop_t *stop;
172 int i;
173
174 if(radial->flags & RDF_DIRTY) {
175 ptn = cairo_pattern_create_radial(radial->cx, radial->cy, 0,
176 radial->cx, radial->cy,
177 radial->r);
178 ASSERT(ptn != NULL);
179 stop = radial->stops;
180 for(i = 0; i < radial->n_stops; i++, stop++) {
181 cairo_pattern_add_color_stop_rgba(ptn, stop->offset,
182 stop->r, stop->g,
183 stop->b, stop->a);
184 }
185 cairo_pattern_destroy(radial->ptn);
186 radial->ptn = ptn;
187 }
188 cairo_set_source(cr, radial->ptn);
189 }
190
191 static void paint_radial_free(paint_t *paint) {
192 paint_radial_t *radial = (paint_radial_t *)paint;
193
194 if(radial->ptn)
195 cairo_pattern_destroy(radial->ptn);
196 free(paint);
197 }
198
199 paint_t *paint_radial_new(redraw_man_t *rdman,
200 co_aix cx, co_aix cy, co_aix r,
201 int n_stops, grad_stop_t *stops) {
202 paint_radial_t *radial;
203
204 radial = O_ALLOC(paint_radial_t);
205 if(radial == NULL)
206 return NULL;
207
208 paint_init(&radial->paint, paint_radial_prepare, paint_radial_free);
209 radial->cx = cx;
210 radial->cy = cy;
211 radial->r = r;
212 radial->n_stops = n_stops;
213 radial->stops = stops;
214 radial->flags = RDF_DIRTY;
215 radial->ptn = NULL;
216
217 return (paint_t *)radial;
218 }
219
220 grad_stop_t *paint_radial_stops(paint_t *paint,
221 int n_stops,
222 grad_stop_t *stops) {
223 paint_radial_t *radial = (paint_radial_t *)paint;
224 grad_stop_t *old_stops;
225
226 old_stops = radial->stops;
227 radial->n_stops = n_stops;
228 radial->stops = stops;
229 radial->flags |= RDF_DIRTY;
230
231 return old_stops;
232 }
233