gf.mode = GLITZ_GEOMETRY_MODE_DIRECT; gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH; gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS; gf.type = GLITZ_DATA_TYPE_FLOAT; gf.first = 0; gf.count = n_traps * 4;  data = malloc (n_traps * 8 * sizeof (glitz_float_t)); if (!data) return CAIRO_STATUS_NO_MEMORY;  buffer = glitz_buffer_create_for_data (data); if (buffer == NULL) { free (data); return CAIRO_STATUS_NO_MEMORY; }  x_dst = traps[0].left.p1.x >> 16; y_dst = traps[0].left.p1.y >> 16;  vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY); for (; n_traps; traps++, n_traps--) { glitz_float_t top, bottom;  top = GLITZ_FIXED_TO_FLOAT (traps->top); bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom);  *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top); *vertices++ = top; *vertices++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top); *vertices++ = top; *vertices++ = GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom); *vertices++ = bottom; *vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom); *vertices++ = bottom; } glitz_buffer_unmap (buffer);  if ((src->pattern.type == CAIRO_PATTERN_SURFACE) && (src->pattern.color.alpha != 1.0)) { glitz_color_t color;  color.red = color.green = color.blue = 0; color.alpha = src->pattern.color.alpha_short;  mask = _glitz_surface_create_solid (dst->surface, GLITZ_STANDARD_A8, &color); }  x_rel = (src->pattern_box.p1.x >> 16) + x_src - x_dst; y_rel = (src->pattern_box.p1.y >> 16) + y_src - y_dst;  x_dst = src->pattern_box.p1.x >> 16; y_dst = src->pattern_box.p1.y >> 16;  width = ((src->pattern_box.p2.x + 65535) >> 16) - (src->pattern_box.p1.x >> 16); height = ((src->pattern_box.p2.y + 65535) >> 16) - (src->pattern_box.p1.y >> 16);  status = _glitz_composite (_glitz_operator (op), src->surface, mask, dst->surface, x_rel, y_rel, 0, 0, x_dst, y_dst, width, height, buffer, &gf);
if (pattern->type == CAIRO_PATTERN_SURFACE) { cairo_pattern_union_t tmp;  _cairo_pattern_init_copy (&tmp.base, pattern); _cairo_pattern_set_alpha (&tmp.base, 1.0);  status = _cairo_glitz_pattern_acquire_surface (&tmp.base, dst, src_x, src_y, width, height, &src, &attributes);  _cairo_pattern_fini (&tmp.base);  alpha = pattern->alpha * 0xffff; } else { status = _cairo_glitz_pattern_acquire_surface (pattern, dst, src_x, src_y, width, height, &src, &attributes); alpha = 0xffff; }  if (status) return status;  if (op == CAIRO_OPERATOR_ADD || n_traps <= 1) { static glitz_color_t	clear_black = { 0, 0, 0, 0 }; glitz_color_t		color; glitz_geometry_format_t	format; int			n_trap_added; int			offset = 0; int			data_size = 0; int			size = 30 * n_traps;   format.vertex.primitive = GLITZ_PRIMITIVE_QUADS; format.vertex.type = GLITZ_DATA_TYPE_FLOAT; format.vertex.bytes_per_vertex = 3 * sizeof (glitz_float_t); format.vertex.attributes = GLITZ_VERTEX_ATTRIBUTE_MASK_COORD_MASK; format.vertex.mask.type = GLITZ_DATA_TYPE_FLOAT; format.vertex.mask.size = GLITZ_COORDINATE_SIZE_X; format.vertex.mask.offset = 2 * sizeof (glitz_float_t);  mask = (cairo_glitz_surface_t *) _cairo_glitz_surface_create_similar (&dst->base, CAIRO_FORMAT_A8, 0, 2, 1); if (!mask) { _cairo_glitz_pattern_release_surface (dst, src, &attributes); return CAIRO_INT_STATUS_UNSUPPORTED; }  color.red = color.green = color.blue = color.alpha = alpha;  glitz_set_rectangle (mask->surface, &clear_black, 0, 0, 1, 1); glitz_set_rectangle (mask->surface, &color, 1, 0, 1, 1);  glitz_surface_set_fill (mask->surface, GLITZ_FILL_NEAREST); glitz_surface_set_filter (mask->surface, GLITZ_FILTER_BILINEAR, NULL, 0);  size *= format.vertex.bytes_per_vertex;  while (n_traps) { if (data_size < size) { data_size = size; data = realloc (data, data_size); if (!data) { _cairo_glitz_pattern_release_surface (dst, src, &attributes); return CAIRO_STATUS_NO_MEMORY; }  if (buffer) glitz_buffer_destroy (buffer);  buffer = glitz_buffer_create_for_data (data); if (!buffer) { free (data); _cairo_glitz_pattern_release_surface (dst, src, &attributes); return CAIRO_STATUS_NO_MEMORY; } }  offset += glitz_add_trapezoids (buffer, offset, size - offset, format.vertex.type, mask->surface, (glitz_trapezoid_t *) traps, n_traps, &n_trap_added);  n_traps -= n_trap_added; traps   += n_trap_added; size    *= 2; }  glitz_set_geometry (dst->surface, GLITZ_GEOMETRY_TYPE_VERTEX, &format, buffer); glitz_set_array (dst->surface, 0, 3, offset / format.vertex.bytes_per_vertex, 0, 0); } else { cairo_image_surface_t *image; char		      *ptr; int		      stride;  stride = (width + 3) & -4; data = malloc (stride * height); if (!data) { _cairo_glitz_pattern_release_surface (dst, src, &attributes); return CAIRO_STATUS_NO_MEMORY; }  memset (data, 0, stride * height);   ptr = (char *) data + stride * (height - 1);  image = (cairo_image_surface_t *) cairo_image_surface_create_for_data (ptr, CAIRO_FORMAT_A8, width, height, -stride); if (!image) { cairo_surface_destroy (&src->base); free (data); return CAIRO_STATUS_NO_MEMORY; }  pixman_add_trapezoids (image->pixman_image, -dst_x, -dst_y, (pixman_trapezoid_t *) traps, n_traps);  if (alpha != 0xffff) { pixman_color_t color;  color.red = color.green = color.blue = color.alpha = alpha;  pixman_fill_rectangle (PIXMAN_OPERATOR_IN, image->pixman_image, &color, 0, 0, width, height); }  mask = (cairo_glitz_surface_t *) _cairo_surface_create_similar_scratch (&dst->base, CAIRO_FORMAT_A8, 0, width, height); if (!mask) { _cairo_glitz_pattern_release_surface (dst, src, &attributes); free (data); cairo_surface_destroy (&image->base); return CAIRO_STATUS_NO_MEMORY; }  _cairo_glitz_surface_set_image (mask, image, 0, 0); }  _cairo_glitz_surface_set_attributes (src, &attributes);  glitz_composite (_glitz_operator (op), src->surface, mask->surface, dst->surface, src_x + attributes.base.x_offset, src_y + attributes.base.y_offset, 0, 0, dst_x, dst_y, width, height);  if (attributes.n_params) free (attributes.params);  glitz_set_geometry (dst->surface, GLITZ_GEOMETRY_TYPE_NONE, NULL, NULL);  if (buffer) glitz_buffer_destroy (buffer);  free (data);  _cairo_glitz_pattern_release_surface (dst, src, &attributes);
_cairo_glitz_surface_composite_trapezoids (cairo_operator_t op,					   cairo_surface_t *generic_src,					   void *abstract_dst,					   int x_src,					   int y_src,					   cairo_trapezoid_t *traps,					   int n_traps){    cairo_glitz_surface_t *dst = abstract_dst;    cairo_glitz_surface_t *src = (cairo_glitz_surface_t *) generic_src;    glitz_surface_t *mask = NULL;    glitz_float_t *vertices;    glitz_buffer_t *buffer;    glitz_geometry_format_t gf;    cairo_int_status_t status;    int x_dst, y_dst, x_rel, y_rel, width, height;    void *data;    if (op == CAIRO_OPERATOR_SATURATE)	return CAIRO_INT_STATUS_UNSUPPORTED;    if (generic_src->backend != dst->base.backend)	return CAIRO_INT_STATUS_UNSUPPORTED;    gf.mode = GLITZ_GEOMETRY_MODE_DIRECT;    gf.edge_hint = GLITZ_GEOMETRY_EDGE_HINT_GOOD_SMOOTH;    gf.primitive = GLITZ_GEOMETRY_PRIMITIVE_QUADS;    gf.type = GLITZ_DATA_TYPE_FLOAT;    gf.first = 0;    gf.count = n_traps * 4;    data = malloc (n_traps * 8 * sizeof (glitz_float_t));    if (!data)	return CAIRO_STATUS_NO_MEMORY;    buffer = glitz_buffer_create_for_data (data);    if (buffer == NULL) {	free (data);	return CAIRO_STATUS_NO_MEMORY;    }	    x_dst = traps[0].left.p1.x >> 16;    y_dst = traps[0].left.p1.y >> 16;	    vertices = glitz_buffer_map (buffer, GLITZ_BUFFER_ACCESS_WRITE_ONLY);    for (; n_traps; traps++, n_traps--) {	glitz_float_t top, bottom;	top = GLITZ_FIXED_TO_FLOAT (traps->top);	bottom = GLITZ_FIXED_TO_FLOAT (traps->bottom);		*vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->top);	*vertices++ = top;	*vertices++ =	    GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->top);	*vertices++ = top;	*vertices++ =	    GLITZ_FIXED_LINE_X_CEIL_TO_FLOAT (traps->right, traps->bottom);	*vertices++ = bottom;	*vertices++ = GLITZ_FIXED_LINE_X_TO_FLOAT (traps->left, traps->bottom);	*vertices++ = bottom;    }    glitz_buffer_unmap (buffer);    if ((src->pattern.type == CAIRO_PATTERN_SURFACE) &&	(src->pattern.color.alpha != 1.0)) {	glitz_color_t color;		color.red = color.green = color.blue = 0;	color.alpha = src->pattern.color.alpha_short;    	mask = _glitz_surface_create_solid (dst->surface,					    GLITZ_STANDARD_A8,					    &color);    }    x_rel = (src->pattern_box.p1.x >> 16) + x_src - x_dst;    y_rel = (src->pattern_box.p1.y >> 16) + y_src - y_dst;    x_dst = src->pattern_box.p1.x >> 16;    y_dst = src->pattern_box.p1.y >> 16;        width = ((src->pattern_box.p2.x + 65535) >> 16) -	(src->pattern_box.p1.x >> 16);    height = ((src->pattern_box.p2.y + 65535) >> 16) -	(src->pattern_box.p1.y >> 16);        status = _glitz_composite (_glitz_operator (op),			       src->surface,			       mask,			       dst->surface,			       x_rel, y_rel,			       0, 0,			       x_dst, y_dst,			       width, height,			       buffer, &gf);    if (mask)	glitz_surface_destroy (mask);    glitz_buffer_destroy (buffer);    free (data);        return status;}