[cairo] [patch] gl: fix gradient color texture generation

Henry (Yu) Song - SISA hsong at sisa.samsung.com
Thu Jul 26 15:23:05 PDT 2012


Hi, Chris and Soren

Hope I got it right this time, tested 

>From 1031bb120239287b351ed772084bb7048d296512 Mon Sep 17 00:00:00 2001
From: Henry Song <henry.song at samsung.com>
Date: Thu, 26 Jul 2012 14:10:19 -0700
Subject: [PATCH 1/2] gl: fix gradient color generation if first few stops are
 offset at 0

---
 src/cairo-gl-gradient.c |   33 ++++++++++++++++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/cairo-gl-gradient.c b/src/cairo-gl-gradient.c
index 76920da..ea91fe9 100644
--- a/src/cairo-gl-gradient.c
+++ b/src/cairo-gl-gradient.c
@@ -97,6 +97,8 @@ _cairo_gl_gradient_render (const cairo_gl_context_t    *ctx,
     pixman_point_fixed_t p1, p2;
     unsigned int i;
     pixman_format_code_t gradient_pixman_format;
+    double min_offset = 0.001;
+    int first_stop = 0;
 
     /*
      * Ensure that the order of the gradient's components in memory is BGRA.
@@ -116,7 +118,36 @@ _cairo_gl_gradient_render (const cairo_gl_context_t    *ctx,
 	    return _cairo_error (CAIRO_STATUS_NO_MEMORY);
     }
 
-    for (i = 0; i < n_stops; i++) {
+    /* pixman always picks color at the right most side of stops if
+     * multiple stops have a same offset.  This is actually a correct 
+     * behaviro.  However, this means if we have two
+     * first stops at (0, 1, 1, 1, 1) and (0, 0, 0, 0, 1), the first
+     * pixel generated is black color instead of white color.  To
+     * compensate that we need to increase the first stop offset a little
+     * such that pixman picks up the first stop at first pixel.
+     */
+    if (n_stops > 2 &&
+	stops[0].offset == stops[1].offset &&
+	stops[0].offset == 0) {
+	double offset = 0;
+	for (i = 2; i < n_stops; i++) {
+	    offset = stops[i].offset - stops[0].offset;
+
+	    if (offset < min_offset && offset != 0) {
+		min_offset = offset;
+		break;
+	    }
+ 	}
+
+	min_offset /= 2;
+	pixman_stops[0].x = _cairo_fixed_16_16_from_double (stops[0].offset + min_offset);
+	pixman_stops[0].color.red   = stops[0].color.red_short;
+	pixman_stops[0].color.green = stops[0].color.green_short;
+	pixman_stops[0].color.blue  = stops[0].color.blue_short;
+	pixman_stops[0].color.alpha = stops[0].color.alpha_short;
+	first_stop = 1;
+    }
+    for (i = first_stop; i < n_stops; i++) {
 	pixman_stops[i].x = _cairo_fixed_16_16_from_double (stops[i].offset);
 	pixman_stops[i].color.red   = stops[i].color.red_short;
 	pixman_stops[i].color.green = stops[i].color.green_short;
-- 
1.7.9.5


More information about the cairo mailing list