[cairo] Use 8-bit colour values internally

Billy Biggs vektor at dumbterm.net
Mon Aug 22 18:07:35 PDT 2005


  The 16-bit representation of colours (cairo_color_t's shorts) is only
used by the fill_rectangles implementation for the image and Xlib
backends.  However, neither really needs this much precision: pixman and
X both convert back to 8 bit internally by shifting.

  I would rather see cairo internally just store the values as 8-bit.
I'd also rather cairo round rather than truncate and push towards 1.  I
admit that this is a matter of taste and not correctness.  Some test
output would change, for example the 0.3 used in the linear-gradient
test will map to 77/255 rather than 76/255.

  Worth it?

  -Billy

-------------- next part --------------
Index: cairo-color.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-color.c,v
retrieving revision 1.15
diff -p -u -r1.15 cairo-color.c
--- cairo-color.c	13 Aug 2005 08:04:55 -0000	1.15
+++ cairo-color.c	23 Aug 2005 00:46:26 -0000
@@ -38,13 +38,13 @@
 #include "cairoint.h"
 
 static cairo_color_t const cairo_color_white = {
-    1.0,    1.0,    1.0,    1.0,
-    0xffff, 0xffff, 0xffff, 0xffff
+    1.0,  1.0,  1.0,  1.0,
+    0xff, 0xff, 0xff, 0xff
 };
 
 static cairo_color_t const cairo_color_black = {
     0.0, 0.0, 0.0, 1.0,
-    0x0, 0x0, 0x0, 0xffff
+    0x0, 0x0, 0x0, 0xff
 };
 
 static cairo_color_t const cairo_color_transparent = {
@@ -53,8 +53,8 @@ static cairo_color_t const cairo_color_t
 };
 
 static cairo_color_t const cairo_color_magenta = {
-    1.0,    0.0, 1.0,    1.0,
-    0xffff, 0x0, 0xffff, 0xffff
+    1.0,  0.0, 1.0,  1.0,
+    0xff, 0x0, 0xff, 0xff
 };
 
 const cairo_color_t *
@@ -89,19 +89,13 @@ _cairo_color_init_rgb (cairo_color_t *co
     _cairo_color_init_rgba (color, red, green, blue, 1.0);
 }
 
-/* We multiply colors by (0x10000 - epsilon), such that we get a uniform
- * range even for 0xffff.  In other words, (1.0 - epsilon) would convert
- * to 0xffff, not 0xfffe.
- */
-#define CAIRO_COLOR_ONE_MINUS_EPSILON (65536.0 - 1e-5)
-
 static void
-_cairo_color_compute_shorts (cairo_color_t *color)
+_cairo_color_compute_chars (cairo_color_t *color)
 {
-    color->red_short   = color->red   * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
-    color->green_short = color->green * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
-    color->blue_short  = color->blue  * color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
-    color->alpha_short = color->alpha * CAIRO_COLOR_ONE_MINUS_EPSILON;
+    color->red_char   = floor (color->red   * color->alpha * 255.0 + 0.5);
+    color->green_char = floor (color->green * color->alpha * 255.0 + 0.5);
+    color->blue_char  = floor (color->blue  * color->alpha * 255.0 + 0.5);
+    color->alpha_char = floor (color->alpha * 255.0 + 0.5);
 }
 
 void
@@ -114,7 +108,7 @@ _cairo_color_init_rgba (cairo_color_t *c
     color->blue  = blue;
     color->alpha = alpha;
 
-    _cairo_color_compute_shorts (color);
+    _cairo_color_compute_chars (color);
 }
 
 void
@@ -123,7 +117,7 @@ _cairo_color_multiply_alpha (cairo_color
 {
     color->alpha *= alpha;
 
-    _cairo_color_compute_shorts (color);
+    _cairo_color_compute_chars (color);
 }
 
 void
Index: cairo-image-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-image-surface.c,v
retrieving revision 1.59
diff -p -u -r1.59 cairo-image-surface.c
--- cairo-image-surface.c	18 Aug 2005 22:50:36 -0000	1.59
+++ cairo-image-surface.c	23 Aug 2005 00:46:26 -0000
@@ -648,10 +648,10 @@ _cairo_image_surface_fill_rectangles (vo
 
     pixman_color_t pixman_color;
 
-    pixman_color.red   = color->red_short;
-    pixman_color.green = color->green_short;
-    pixman_color.blue  = color->blue_short;
-    pixman_color.alpha = color->alpha_short;
+    pixman_color.red   = color->red_char << 8;
+    pixman_color.green = color->green_char << 8;
+    pixman_color.blue  = color->blue_char << 8;
+    pixman_color.alpha = color->alpha_char << 8;
 
     /* XXX: The pixman_rectangle_t cast is evil... it needs to go away somehow. */
     pixman_fill_rectangles (_pixman_operator(operator), surface->pixman_image,
Index: cairo-xlib-surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo-xlib-surface.c,v
retrieving revision 1.114
diff -p -u -r1.114 cairo-xlib-surface.c
--- cairo-xlib-surface.c	21 Aug 2005 15:11:24 -0000	1.114
+++ cairo-xlib-surface.c	23 Aug 2005 00:46:27 -0000
@@ -1214,10 +1214,10 @@ _cairo_xlib_surface_fill_rectangles (voi
     if (!CAIRO_SURFACE_RENDER_HAS_FILL_RECTANGLE (surface))
 	return CAIRO_INT_STATUS_UNSUPPORTED;
 
-    render_color.red   = color->red_short;
-    render_color.green = color->green_short;
-    render_color.blue  = color->blue_short;
-    render_color.alpha = color->alpha_short;
+    render_color.red   = color->red_char << 8;
+    render_color.green = color->green_char << 8;
+    render_color.blue  = color->blue_char << 8;
+    render_color.alpha = color->alpha_char << 8;
 
     /* XXX: This XRectangle cast is evil... it needs to go away somehow. */
     _cairo_xlib_surface_ensure_dst_picture (surface);
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.202
diff -p -u -r1.202 cairoint.h
--- cairoint.h	22 Aug 2005 04:04:52 -0000	1.202
+++ cairoint.h	23 Aug 2005 00:46:28 -0000
@@ -177,8 +177,8 @@ typedef cairo_fixed_16_16_t cairo_fixed_
 #define CAIRO_MAXSHORT SHRT_MAX
 #define CAIRO_MINSHORT SHRT_MIN
 
-#define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) >= ((double)0xff00 / (double)0xffff))
-#define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) <= 0.0)
+#define CAIRO_ALPHA_IS_OPAQUE(alpha) ((alpha) > ((double)0xfe / (double)0xff))
+#define CAIRO_ALPHA_IS_ZERO(alpha) ((alpha) < ((double)0x1 / (double)0xff))
 
 #include "cairo-hash-private.h"
 
@@ -902,10 +902,10 @@ struct _cairo_color {
     double blue;
     double alpha;
 
-    unsigned short red_short;
-    unsigned short green_short;
-    unsigned short blue_short;
-    unsigned short alpha_short;
+    unsigned char red_char;
+    unsigned char green_char;
+    unsigned char blue_char;
+    unsigned char alpha_char;
 };
 
 typedef enum {


More information about the cairo mailing list