00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <cairo.h>
00004 #include "mb_paint.h"
00005
00006 #define ASSERT(x)
00007
00008
00009
00010 typedef struct _paint_color {
00011 paint_t paint;
00012 co_comp_t r, g, b, a;
00013 } paint_color_t;
00014
00015 int _paint_color_size = sizeof(paint_color_t);
00016
00017
00018 static void paint_color_prepare(paint_t *paint, cairo_t *cr) {
00019 paint_color_t *color = (paint_color_t *)paint;
00020
00021 cairo_set_source_rgba(cr, color->r, color->g, color->b, color->a);
00022 }
00023
00024 static void paint_color_free(redraw_man_t *rdman, paint_t *paint) {
00025 shnode_list_free(rdman, paint->members);
00026 elmpool_elm_free(rdman->paint_color_pool, paint);
00027 }
00028
00029 paint_t *rdman_paint_color_new(redraw_man_t *rdman,
00030 co_comp_t r, co_comp_t g,
00031 co_comp_t b, co_comp_t a) {
00032 paint_color_t *color;
00033
00034 color = (paint_color_t *)elmpool_elm_alloc(rdman->paint_color_pool);
00035 if(color == NULL)
00036 return NULL;
00037 color->r = r;
00038 color->g = g;
00039 color->b = b;
00040 color->a = a;
00041 paint_init(&color->paint, paint_color_prepare, paint_color_free);
00042 return (paint_t *)color;
00043 }
00044
00045 void paint_color_set(paint_t *paint,
00046 co_comp_t r, co_comp_t g,
00047 co_comp_t b, co_comp_t a) {
00048 paint_color_t *color = (paint_color_t *)paint;
00049
00050 color->r = r;
00051 color->g = g;
00052 color->b = b;
00053 color->a = a;
00054 }
00055
00056 void paint_color_get(paint_t *paint,
00057 co_comp_t *r, co_comp_t *g,
00058 co_comp_t *b, co_comp_t *a) {
00059 paint_color_t *color = (paint_color_t *)paint;
00060
00061 *r = color->r;
00062 *g = color->g;
00063 *b = color->b;
00064 *a = color->a;
00065 }
00066
00067
00068
00069 typedef struct _paint_linear {
00070 paint_t paint;
00071 co_aix x1, y1;
00072 co_aix x2, y2;
00073 int n_stops;
00074 grad_stop_t *stops;
00075 int flags;
00076 cairo_pattern_t *ptn;
00077 } paint_linear_t;
00078
00079 #define LIF_DIRTY 0x1
00080
00081 static void paint_linear_prepare(paint_t *paint, cairo_t *cr) {
00082 paint_linear_t *linear = (paint_linear_t *)paint;
00083 cairo_pattern_t *ptn;
00084 grad_stop_t *stop;
00085 int i;
00086
00087 ptn = linear->ptn;
00088 if(linear->flags & LIF_DIRTY) {
00089 if(ptn)
00090 cairo_pattern_destroy(ptn);
00091 linear->flags &= ~LIF_DIRTY;
00092 ptn = cairo_pattern_create_linear(linear->x1, linear->y1,
00093 linear->x2, linear->y2);
00094 for(i = 0; i < linear->n_stops; i++) {
00095 stop = &linear->stops[i];
00096 cairo_pattern_add_color_stop_rgba(ptn, stop->offset,
00097 stop->r, stop->g, stop->b,
00098 stop->a);
00099 }
00100 linear->ptn = ptn;
00101 }
00102
00103 cairo_set_source(cr, ptn);
00104 }
00105
00106 static void paint_linear_free(redraw_man_t *rdman, paint_t *paint) {
00107 paint_linear_t *linear = (paint_linear_t *)paint;
00108
00109 if(linear->ptn)
00110 cairo_pattern_destroy(linear->ptn);
00111 free(paint);
00112 }
00113
00114 paint_t *rdman_paint_linear_new(redraw_man_t *rdman,
00115 co_aix x1, co_aix y1,
00116 co_aix x2, co_aix y2) {
00117 paint_linear_t *linear;
00118
00119 linear = (paint_linear_t *)malloc(sizeof(paint_linear_t));
00120 if(linear == NULL)
00121 return NULL;
00122
00123 paint_init(&linear->paint, paint_linear_prepare, paint_linear_free);
00124
00125 linear->x1 = x1;
00126 linear->y1 = y1;
00127 linear->x2 = x2;
00128 linear->y2 = y2;
00129 linear->n_stops = 0;
00130 linear->stops = NULL;
00131 linear->flags = LIF_DIRTY;
00132 linear->ptn = NULL;
00133
00134 return (paint_t *)linear;
00135 }
00136
00137
00138
00139
00140
00141
00142
00143 grad_stop_t *paint_linear_stops(paint_t *paint,
00144 int n_stops,
00145 grad_stop_t *stops) {
00146 paint_linear_t *linear = (paint_linear_t *)paint;
00147 grad_stop_t *old_stops;
00148
00149 old_stops = linear->stops;
00150 linear->n_stops = n_stops;
00151 linear->stops = stops;
00152 linear->flags |= LIF_DIRTY;
00153
00154 return old_stops;
00155 }
00156
00157
00158
00159
00160
00161 typedef struct _paint_radial {
00162 paint_t paint;
00163 co_aix cx, cy;
00164 co_aix r;
00165 int n_stops;
00166 grad_stop_t *stops;
00167 int flags;
00168 cairo_pattern_t *ptn;
00169 } paint_radial_t;
00170
00171 #define RDF_DIRTY 0x1
00172
00173 static void paint_radial_prepare(paint_t *paint, cairo_t *cr) {
00174 paint_radial_t *radial = (paint_radial_t *)paint;
00175 cairo_pattern_t *ptn;
00176 grad_stop_t *stop;
00177 int i;
00178
00179 if(radial->flags & RDF_DIRTY) {
00180 ptn = cairo_pattern_create_radial(radial->cx, radial->cy, 0,
00181 radial->cx, radial->cy,
00182 radial->r);
00183 ASSERT(ptn != NULL);
00184 stop = radial->stops;
00185 for(i = 0; i < radial->n_stops; i++, stop++) {
00186 cairo_pattern_add_color_stop_rgba(ptn, stop->offset,
00187 stop->r, stop->g,
00188 stop->b, stop->a);
00189 }
00190 cairo_pattern_destroy(radial->ptn);
00191 radial->ptn = ptn;
00192 }
00193 cairo_set_source(cr, radial->ptn);
00194 }
00195
00196 static void paint_radial_free(redraw_man_t *rdman, paint_t *paint) {
00197 paint_radial_t *radial = (paint_radial_t *)paint;
00198
00199 if(radial->ptn)
00200 cairo_pattern_destroy(radial->ptn);
00201 free(paint);
00202 }
00203
00204 paint_t *rdman_paint_radial_new(redraw_man_t *rdman,
00205 co_aix cx, co_aix cy, co_aix r) {
00206 paint_radial_t *radial;
00207
00208 radial = O_ALLOC(paint_radial_t);
00209 if(radial == NULL)
00210 return NULL;
00211
00212 paint_init(&radial->paint, paint_radial_prepare, paint_radial_free);
00213 radial->cx = cx;
00214 radial->cy = cy;
00215 radial->r = r;
00216 radial->n_stops = 0;
00217 radial->stops = NULL;
00218 radial->flags = RDF_DIRTY;
00219 radial->ptn = NULL;
00220
00221 return (paint_t *)radial;
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 grad_stop_t *paint_radial_stops(paint_t *paint,
00231 int n_stops,
00232 grad_stop_t *stops) {
00233 paint_radial_t *radial = (paint_radial_t *)paint;
00234 grad_stop_t *old_stops;
00235
00236 old_stops = radial->stops;
00237 radial->n_stops = n_stops;
00238 radial->stops = stops;
00239 radial->flags |= RDF_DIRTY;
00240
00241 return old_stops;
00242 }
00243