[cairo-commit] cairo/src cairo_gl_surface.c, 1.2,
1.3 cairo_pattern.c, 1.4, 1.5 cairo_surface.c, 1.28,
1.29 cairoint.h, 1.58, 1.59
David Reveman
commit at pdx.freedesktop.org
Sun Apr 25 04:02:40 PDT 2004
Committed by: davidr
Update of /cvs/cairo/cairo/src
In directory pdx:/tmp/cvs-serv19262/src
Modified Files:
cairo_gl_surface.c cairo_pattern.c cairo_surface.c cairoint.h
Log Message:
Converted shading routines to use fixed point values.
Index: cairo_gl_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_gl_surface.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** a/cairo_gl_surface.c 22 Apr 2004 09:22:36 -0000 1.2
--- b/cairo_gl_surface.c 25 Apr 2004 11:02:38 -0000 1.3
***************
*** 383,386 ****
--- 383,390 ----
cairo_gl_surface_t *mask_clone = NULL;
+ /* Make sure that target surface is OK. */
+ if (glitz_surface_get_status (dst->surface))
+ return CAIRO_STATUS_NO_TARGET_SURFACE;
+
/* If destination surface is offscreen, then offscreen drawing support is
required. */
***************
*** 441,444 ****
--- 445,452 ----
glitz_color_t glitz_color;
+ /* Make sure that target surface is OK. */
+ if (glitz_surface_get_status (surface->surface))
+ return CAIRO_STATUS_NO_TARGET_SURFACE;
+
/* If destination surface is offscreen, then offscreen drawing support is
required. */
***************
*** 496,499 ****
--- 504,511 ----
cairo_gl_surface_t *src_clone = NULL;
+ /* Make sure that target surface is OK. */
+ if (glitz_surface_get_status (dst->surface))
+ return CAIRO_STATUS_NO_TARGET_SURFACE;
+
/* If destination surface is offscreen, then offscreen drawing support is
required. */
***************
*** 502,506 ****
return CAIRO_INT_STATUS_UNSUPPORTED;
! /* Need to get current hints as clipping might have changed. */
dst->hints = glitz_surface_get_hints (dst->surface);
--- 514,518 ----
return CAIRO_INT_STATUS_UNSUPPORTED;
! /* Need to get current hints as clipping may have changed. */
dst->hints = glitz_surface_get_hints (dst->surface);
***************
*** 571,577 ****
{
unsigned int i, bytes = size * 4;
for (i = 0; i < bytes; i += 4)
! _cairo_pattern_calc_color_at_pixel (pattern, i / (double) bytes,
(int *) &data[i]);
}
--- 583,593 ----
{
unsigned int i, bytes = size * 4;
+ cairo_shader_op_t op;
+
+ _cairo_pattern_shader_init (pattern, &op);
for (i = 0; i < bytes; i += 4)
! _cairo_pattern_calc_color_at_pixel (&op,
! ((double) i / bytes) * 65536,
(int *) &data[i]);
}
***************
*** 585,590 ****
glitz_surface_t *programmatic = NULL;
cairo_gl_surface_t *gl_surface;
! double bbox_x = floor (_cairo_fixed_to_double (box->p1.x));
! double bbox_y = floor (_cairo_fixed_to_double (box->p1.y));
double x = bbox_x + pattern->source_offset.x;
double y = bbox_y + pattern->source_offset.y;
--- 601,606 ----
glitz_surface_t *programmatic = NULL;
cairo_gl_surface_t *gl_surface;
! double bbox_x = box->p1.x >> 16;
! double bbox_y = box->p1.y >> 16;
double x = bbox_x + pattern->source_offset.x;
double y = bbox_y + pattern->source_offset.y;
***************
*** 627,631 ****
color_range_size = sqrt (dx * dx + dy * dy);
} else {
! /* libglitz doesn't support inner circle. */
if (pattern->u.radial.center0.x !=
pattern->u.radial.center1.x
--- 643,647 ----
color_range_size = sqrt (dx * dx + dy * dy);
} else {
! /* glitz doesn't support inner circle yet. */
if (pattern->u.radial.center0.x !=
pattern->u.radial.center1.x
***************
*** 681,685 ****
glitz_point_fixed_t center;
glitz_distance_fixed_t radius;
!
center.x =
_cairo_fixed_from_double (pattern->u.radial.center1.x - x);
--- 697,701 ----
glitz_point_fixed_t center;
glitz_distance_fixed_t radius;
!
center.x =
_cairo_fixed_from_double (pattern->u.radial.center1.x - x);
***************
*** 758,765 ****
for (i = 0; i < n; n++, box++) {
! clip_rects[i].x = (short) box->x1;
! clip_rects[i].y = (short) box->y1;
! clip_rects[i].width = (unsigned short) (box->x2 - box->x1);
! clip_rects[i].height = (unsigned short) (box->y2 - box->y1);
}
--- 774,781 ----
for (i = 0; i < n; n++, box++) {
! clip_rects[i].x = (short) (box->x1 >> 16);
! clip_rects[i].y = (short) (box->y1 >> 16);
! clip_rects[i].width = (unsigned short) ((box->x2 - box->x1) >> 16);
! clip_rects[i].height = (unsigned short) ((box->y2 - box->y1) >> 16);
}
Index: cairo_pattern.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_pattern.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** a/cairo_pattern.c 22 Apr 2004 09:22:36 -0000 1.4
--- b/cairo_pattern.c 25 Apr 2004 11:02:38 -0000 1.5
***************
*** 176,185 ****
pattern->u.radial.center0.x = cx0;
pattern->u.radial.center0.y = cy0;
! pattern->u.radial.radius0.dx = radius0;
! pattern->u.radial.radius0.dy = radius0;
pattern->u.radial.center1.x = cx1;
pattern->u.radial.center1.y = cy1;
! pattern->u.radial.radius1.dx = radius1;
! pattern->u.radial.radius1.dy = radius1;
return pattern;
--- 176,185 ----
pattern->u.radial.center0.x = cx0;
pattern->u.radial.center0.y = cy0;
! pattern->u.radial.radius0.dx = fabs (radius0);
! pattern->u.radial.radius0.dy = fabs (radius0);
pattern->u.radial.center1.x = cx1;
pattern->u.radial.center1.y = cy1;
! pattern->u.radial.radius1.dx = fabs (radius1);
! pattern->u.radial.radius1.dy = fabs (radius1);
return pattern;
***************
*** 230,233 ****
--- 230,234 ----
{
cairo_color_stop_t *stop;
+ int i;
_cairo_restrict_value (&offset, 0.0, 1.0);
***************
*** 247,251 ****
stop = &pattern->stops[pattern->n_stops - 1];
! stop->offset = offset;
stop->id = pattern->n_stops;
_cairo_color_init (&stop->color);
--- 248,252 ----
stop = &pattern->stops[pattern->n_stops - 1];
! stop->offset = _cairo_fixed_from_double (offset);
stop->id = pattern->n_stops;
_cairo_color_init (&stop->color);
***************
*** 261,264 ****
--- 262,272 ----
_cairo_pattern_stop_compare);
+ for (i = 0; i < pattern->n_stops - 1; i++) {
+ pattern->stops[i + 1].scale =
+ pattern->stops[i + 1].offset - pattern->stops[i].offset;
+ if (pattern->stops[i + 1].scale == 65536)
+ pattern->stops[i + 1].scale = 0;
+ }
+
return CAIRO_STATUS_SUCCESS;
}
***************
*** 350,354 ****
{
cairo_matrix_t matrix;
!
switch (pattern->type) {
case CAIRO_PATTERN_SURFACE:
--- 358,362 ----
{
cairo_matrix_t matrix;
!
switch (pattern->type) {
case CAIRO_PATTERN_SURFACE:
***************
*** 420,441 ****
}
- typedef void (*cairo_shader_function_t) (unsigned char *color0,
- unsigned char *color1,
- double factor,
- unsigned char *result_color);
-
#define INTERPOLATE_COLOR_NEAREST(c1, c2, factor) \
! ((unsigned char) ((factor < 0.5)? c1: c2))
static void
_cairo_pattern_shader_nearest (unsigned char *color0,
unsigned char *color1,
! double factor,
! unsigned char *result_color)
{
! result_color[0] = INTERPOLATE_COLOR_NEAREST (color0[0], color1[0], factor);
! result_color[1] = INTERPOLATE_COLOR_NEAREST (color0[1], color1[1], factor);
! result_color[2] = INTERPOLATE_COLOR_NEAREST (color0[2], color1[2], factor);
! result_color[3] = INTERPOLATE_COLOR_NEAREST (color0[3], color1[3], factor);
}
--- 428,445 ----
}
#define INTERPOLATE_COLOR_NEAREST(c1, c2, factor) \
! ((factor < 32768)? c1: c2)
static void
_cairo_pattern_shader_nearest (unsigned char *color0,
unsigned char *color1,
! cairo_fixed_t factor,
! int *pixel)
{
! *pixel =
! ((INTERPOLATE_COLOR_NEAREST (color0[3], color1[3], factor) << 24) |
! (INTERPOLATE_COLOR_NEAREST (color0[0], color1[0], factor) << 16) |
! (INTERPOLATE_COLOR_NEAREST (color0[1], color1[1], factor) << 8) |
! (INTERPOLATE_COLOR_NEAREST (color0[2], color1[2], factor) << 0));
}
***************
*** 443,472 ****
#define INTERPOLATE_COLOR_LINEAR(c1, c2, factor) \
! ((unsigned char) ((c2 * factor) + (c1 * (1.0 - factor))))
static void
_cairo_pattern_shader_linear (unsigned char *color0,
unsigned char *color1,
! double factor,
! unsigned char *result_color)
{
! result_color[0] = INTERPOLATE_COLOR_LINEAR (color0[0], color1[0], factor);
! result_color[1] = INTERPOLATE_COLOR_LINEAR (color0[1], color1[1], factor);
! result_color[2] = INTERPOLATE_COLOR_LINEAR (color0[2], color1[2], factor);
! result_color[3] = INTERPOLATE_COLOR_LINEAR (color0[3], color1[3], factor);
}
static void
_cairo_pattern_shader_gaussian (unsigned char *color0,
unsigned char *color1,
! double factor,
! unsigned char *result_color)
{
! factor = (exp (factor * factor) - 1.0) / (M_E - 1.0);
! result_color[0] = INTERPOLATE_COLOR_LINEAR (color0[0], color1[0], factor);
! result_color[1] = INTERPOLATE_COLOR_LINEAR (color0[1], color1[1], factor);
! result_color[2] = INTERPOLATE_COLOR_LINEAR (color0[2], color1[2], factor);
! result_color[3] = INTERPOLATE_COLOR_LINEAR (color0[3], color1[3], factor);
}
--- 447,480 ----
#define INTERPOLATE_COLOR_LINEAR(c1, c2, factor) \
! (((c2 * factor) + (c1 * (65536 - factor))) / 65536)
static void
_cairo_pattern_shader_linear (unsigned char *color0,
unsigned char *color1,
! cairo_fixed_t factor,
! int *pixel)
{
! *pixel = ((INTERPOLATE_COLOR_LINEAR (color0[3], color1[3], factor) << 24) |
! (INTERPOLATE_COLOR_LINEAR (color0[0], color1[0], factor) << 16) |
! (INTERPOLATE_COLOR_LINEAR (color0[1], color1[1], factor) << 8) |
! (INTERPOLATE_COLOR_LINEAR (color0[2], color1[2], factor) << 0));
}
+ #define E_MINUS_ONE 1.7182818284590452354
+
static void
_cairo_pattern_shader_gaussian (unsigned char *color0,
unsigned char *color1,
! cairo_fixed_t factor,
! int *pixel)
{
! double f = ((double) factor) / 65536.0;
! factor = (cairo_fixed_t) (((exp (f * f) - 1.0) / E_MINUS_ONE) * 65536);
!
! *pixel = ((INTERPOLATE_COLOR_LINEAR (color0[3], color1[3], factor) << 24) |
! (INTERPOLATE_COLOR_LINEAR (color0[0], color1[0], factor) << 16) |
! (INTERPOLATE_COLOR_LINEAR (color0[1], color1[1], factor) << 8) |
! (INTERPOLATE_COLOR_LINEAR (color0[2], color1[2], factor) << 0));
}
***************
*** 474,552 ****
void
! _cairo_pattern_calc_color_at_pixel (cairo_pattern_t *pattern,
! double factor,
! int *pixel)
{
! int p, colorstop;
! double factorscale;
! unsigned char result_color[4];
! cairo_shader_function_t shader_function;
!
switch (pattern->filter) {
case CAIRO_FILTER_FAST:
case CAIRO_FILTER_NEAREST:
! shader_function = _cairo_pattern_shader_nearest;
break;
case CAIRO_FILTER_GAUSSIAN:
! shader_function = _cairo_pattern_shader_gaussian;
break;
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_BILINEAR:
! shader_function = _cairo_pattern_shader_linear;
break;
}
! if (factor > 1.0 || factor < 0.0) {
! switch (pattern->extend) {
! case CAIRO_EXTEND_REPEAT:
! factor -= floor (factor);
! break;
! case CAIRO_EXTEND_REFLECT:
! if (factor >= 0.0) {
! if (((int) factor) % 2)
! factor = 1.0 - (factor - floor (factor));
! else
! factor -= floor (factor);
! } else {
! if (((int) factor) % 2)
! factor -= floor (factor);
! else
! factor = 1.0 - (factor - floor (factor));
! }
! break;
! case CAIRO_EXTEND_NONE:
! break;
}
}
-
- if (factor < pattern->stops[0].offset)
- factor = pattern->stops[0].offset;
-
- if (factor > pattern->stops[pattern->n_stops - 1].offset)
- factor = pattern->stops[pattern->n_stops - 1].offset;
! for (colorstop = 0; colorstop < pattern->n_stops - 1; colorstop++) {
! if (factor <= pattern->stops[colorstop + 1].offset) {
! factorscale = fabs (pattern->stops[colorstop].offset -
! pattern->stops[colorstop + 1].offset);
!
! /* abrubt change, difference between two offsets == 0.0 */
! if (factorscale == 0)
! break;
!
! factor -= pattern->stops[colorstop].offset;
/* take offset as new 0 of coordinate system */
! factor /= factorscale;
!
! shader_function (pattern->stops[colorstop].color_char,
! pattern->stops[colorstop + 1].color_char,
! factor, result_color);
!
! p = ((result_color[3] << 24) |
! (result_color[0] << 16) |
! (result_color[1] << 8) | (result_color[2] << 0));
! *pixel = p;
break;
}
--- 482,557 ----
void
! _cairo_pattern_shader_init (cairo_pattern_t *pattern,
! cairo_shader_op_t *op)
{
! op->stops = pattern->stops;
! op->n_stops = pattern->n_stops - 1;
! op->min_offset = pattern->stops[0].offset;
! op->max_offset = pattern->stops[op->n_stops].offset;
! op->extend = pattern->extend;
!
switch (pattern->filter) {
case CAIRO_FILTER_FAST:
case CAIRO_FILTER_NEAREST:
! op->shader_function = _cairo_pattern_shader_nearest;
break;
case CAIRO_FILTER_GAUSSIAN:
! op->shader_function = _cairo_pattern_shader_gaussian;
break;
case CAIRO_FILTER_GOOD:
case CAIRO_FILTER_BEST:
case CAIRO_FILTER_BILINEAR:
! op->shader_function = _cairo_pattern_shader_linear;
break;
}
+ }
+
+ void
+ _cairo_pattern_calc_color_at_pixel (cairo_shader_op_t *op,
+ cairo_fixed_t factor,
+ int *pixel)
+ {
+ int i;
! switch (op->extend) {
! case CAIRO_EXTEND_REPEAT:
! factor -= factor & 0xffff0000;
! break;
! case CAIRO_EXTEND_REFLECT:
! if (factor < 0) {
! if ((factor >> 16) % 2)
! factor -= factor & 0xffff0000;
! else
! factor = 65536 - (factor - (factor & 0xffff0000));
! } else if (factor > 65536) {
! if ((factor >> 16) % 2)
! factor = 65536 - (factor - (factor & 0xffff0000));
! else
! factor -= factor & 0xffff0000;
}
+ break;
+ case CAIRO_EXTEND_NONE:
+ break;
}
! if (factor < op->min_offset)
! factor = op->min_offset;
! else if (factor > op->max_offset)
! factor = op->max_offset;
+ for (i = 0; i < op->n_stops; i++) {
+ if (factor <= op->stops[i + 1].offset) {
+
/* take offset as new 0 of coordinate system */
! factor -= op->stops[i].offset;
!
! /* difference between two offsets == 0, abrubt change */
! if (op->stops[i + 1].scale)
! factor = ((cairo_fixed_48_16_t) factor << 16) /
! op->stops[i + 1].scale;
!
! op->shader_function (op->stops[i].color_char,
! op->stops[i + 1].color_char,
! factor, pixel);
break;
}
***************
*** 564,570 ****
int x, y;
cairo_point_double_t point0, point1, angle;
! double a, length, start, end;
double factor;
point0.x = pattern->u.linear.point0.x - offset_x;
point0.y = pattern->u.linear.point0.y - offset_y;
--- 569,578 ----
int x, y;
cairo_point_double_t point0, point1, angle;
! double a, length, start;
! cairo_shader_op_t op;
double factor;
+ _cairo_pattern_shader_init (pattern, &op);
+
point0.x = pattern->u.linear.point0.x - offset_x;
point0.y = pattern->u.linear.point0.y - offset_y;
***************
*** 583,599 ****
start += angle.y * point0.y;
- end = angle.x * point1.x;
- end += angle.y * point1.y;
-
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
!
! factor = angle.x * (double) x;
! factor += angle.y * (double) y;
!
! factor = factor - start;
! factor *= length;
! _cairo_pattern_calc_color_at_pixel (pattern, factor, (int *)
&data[y * width * 4 + x * 4]);
}
--- 591,603 ----
start += angle.y * point0.y;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
!
! factor = ((angle.x * (double) x) +
! (angle.y * (double) y) - start) * length;
! _cairo_pattern_calc_color_at_pixel (&op,
! factor * 65536,
! (int *)
&data[y * width * 4 + x * 4]);
}
***************
*** 613,634 ****
cairo_point_double_t center1, pos;
cairo_distance_double_t length;
! double factor;
! double min_length;
center1.x = pattern->u.radial.center1.x - offset_x;
center1.y = pattern->u.radial.center1.y - offset_y;
! min_length =
! fabs ((pattern->u.radial.radius1.dx < pattern->u.radial.radius1.dy) ?
! pattern->u.radial.radius1.dx : pattern->u.radial.radius1.dy);
!
! /* ugly */
! if (min_length == 0.0)
! min_length = 0.000001;
length.dx = min_length / pattern->u.radial.radius1.dx;
length.dy = min_length / pattern->u.radial.radius1.dy;
!
! min_length = 1.0 / min_length;
for (y = 0; y < height; y++) {
--- 617,635 ----
cairo_point_double_t center1, pos;
cairo_distance_double_t length;
! double factor, min_length;
! cairo_shader_op_t op;
!
! _cairo_pattern_shader_init (pattern, &op);
center1.x = pattern->u.radial.center1.x - offset_x;
center1.y = pattern->u.radial.center1.y - offset_y;
! min_length = (pattern->u.radial.radius1.dx < pattern->u.radial.radius1.dy)?
! pattern->u.radial.radius1.dx : pattern->u.radial.radius1.dy;
length.dx = min_length / pattern->u.radial.radius1.dx;
length.dy = min_length / pattern->u.radial.radius1.dy;
!
! min_length = (min_length)? 1.0 / min_length: CAIRO_MAXSHORT;
for (y = 0; y < height; y++) {
***************
*** 642,646 ****
factor = sqrt (pos.x * pos.x + pos.y * pos.y) * min_length;
! _cairo_pattern_calc_color_at_pixel (pattern, factor, (int *)
&data[y * width * 4 + x * 4]);
}
--- 643,649 ----
factor = sqrt (pos.x * pos.x + pos.y * pos.y) * min_length;
! _cairo_pattern_calc_color_at_pixel (&op,
! factor * 65536,
! (int *)
&data[y * width * 4 + x * 4]);
}
***************
*** 657,664 ****
case CAIRO_PATTERN_RADIAL: {
char *data;
! int x = floor (_cairo_fixed_to_double (box->p1.x));
! int y = floor (_cairo_fixed_to_double (box->p1.y));
! int width = ceil (_cairo_fixed_to_double (box->p2.x)) - x;
! int height = ceil (_cairo_fixed_to_double (box->p2.y)) - y;
data = malloc (width * height * 4);
--- 660,667 ----
case CAIRO_PATTERN_RADIAL: {
char *data;
! double x = box->p1.x >> 16;
! double y = box->p1.y >> 16;
! int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16);
! int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16);
data = malloc (width * height * 4);
***************
*** 683,687 ****
width, height,
width * 4);
!
if (surface)
_cairo_image_surface_assume_ownership_of_data (
--- 686,690 ----
width, height,
width * 4);
!
if (surface)
_cairo_image_surface_assume_ownership_of_data (
Index: cairo_surface.c
===================================================================
RCS file: /cvs/cairo/cairo/src/cairo_surface.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -C2 -d -r1.28 -r1.29
*** a/cairo_surface.c 23 Apr 2004 17:08:53 -0000 1.28
--- b/cairo_surface.c 25 Apr 2004 11:02:38 -0000 1.29
***************
*** 425,432 ****
/* handle pattern opacity */
if (pattern->color.alpha != 1.0) {
! int x = floor (_cairo_fixed_to_double (box->p1.x));
! int y = floor (_cairo_fixed_to_double (box->p1.y));
! int width = ceil (_cairo_fixed_to_double (box->p2.x)) - x;
! int height = ceil (_cairo_fixed_to_double (box->p2.y)) - y;
cairo_pattern_t alpha;
--- 425,432 ----
/* handle pattern opacity */
if (pattern->color.alpha != 1.0) {
! double x = box->p1.x >> 16;
! double y = box->p1.y >> 16;
! int width = ((box->p2.x + 65535) >> 16) - (box->p1.x >> 16);
! int height = ((box->p2.y + 65535) >> 16) - (box->p1.y >> 16);
cairo_pattern_t alpha;
Index: cairoint.h
===================================================================
RCS file: /cvs/cairo/cairo/src/cairoint.h,v
retrieving revision 1.58
retrieving revision 1.59
diff -C2 -d -r1.58 -r1.59
*** a/cairoint.h 23 Apr 2004 17:08:53 -0000 1.58
--- b/cairoint.h 25 Apr 2004 11:02:38 -0000 1.59
***************
*** 458,462 ****
typedef struct cairo_color_stop {
! double offset;
int id;
cairo_color_t color;
--- 458,463 ----
typedef struct cairo_color_stop {
! cairo_fixed_t offset;
! cairo_fixed_48_16_t scale;
int id;
cairo_color_t color;
***************
*** 464,467 ****
--- 465,482 ----
} cairo_color_stop_t;
+ typedef void (*cairo_shader_function_t) (unsigned char *color0,
+ unsigned char *color1,
+ cairo_fixed_t factor,
+ int *pixel);
+
+ typedef struct cairo_shader_op {
+ cairo_color_stop_t *stops;
+ int n_stops;
+ cairo_fixed_t min_offset;
+ cairo_fixed_t max_offset;
+ cairo_extend_t extend;
+ cairo_shader_function_t shader_function;
+ } cairo_shader_op_t;
+
struct cairo_pattern {
unsigned int ref_count;
***************
*** 1348,1353 ****
extern void __internal_linkage
! _cairo_pattern_calc_color_at_pixel (cairo_pattern_t *pattern,
! double factor,
int *pixel);
--- 1363,1372 ----
extern void __internal_linkage
! _cairo_pattern_shader_init (cairo_pattern_t *pattern,
! cairo_shader_op_t *op);
!
! extern void __internal_linkage
! _cairo_pattern_calc_color_at_pixel (cairo_shader_op_t *op,
! cairo_fixed_t factor,
int *pixel);
More information about the cairo-commit
mailing list