diff src/paint.c @ 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 83d24300a992
children 59a295651480
line wrap: on
line diff
--- 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;
+}
+