[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