[image] Eliminate the short-lived context used for coercing.

When coercing from one image format to another we performed a paint
operation using a temporary context - this is overkill as we can just call
_cairo_surface_paint() directly.
This commit is contained in:
Chris Wilson 2008-12-17 10:07:32 +00:00
parent 9b46d13b6c
commit 6458903c95
5 changed files with 59 additions and 65 deletions

View file

@ -1524,35 +1524,41 @@ const cairo_surface_backend_t _cairo_image_surface_backend = {
/* A convenience function for when one needs to coerce an image
* surface to an alternate format. */
cairo_image_surface_t *
_cairo_image_surface_clone (cairo_image_surface_t *surface,
cairo_format_t format)
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
cairo_format_t format)
{
cairo_image_surface_t *clone;
cairo_surface_pattern_t pattern;
cairo_status_t status;
cairo_t *cr;
double x, y;
status = surface->base.status;
if (unlikely (status))
return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
if (surface->format == format)
return (cairo_image_surface_t *)cairo_surface_reference(&surface->base);
clone = (cairo_image_surface_t *)
cairo_image_surface_create (format,
surface->width, surface->height);
cairo_image_surface_create (format, surface->width, surface->height);
if (unlikely (clone->base.status))
return clone;
cairo_surface_get_device_offset (&surface->base, &x, &y);
cairo_surface_set_device_offset (&clone->base, x, y);
clone->transparency = CAIRO_IMAGE_UNKNOWN;
/* XXX Use _cairo_surface_composite directly */
cr = cairo_create (&clone->base);
cairo_set_source_surface (cr, &surface->base, 0, 0);
cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
cairo_paint (cr);
status = cairo_status (cr);
cairo_destroy (cr);
_cairo_pattern_init_for_surface (&pattern, &surface->base);
status = _cairo_surface_paint (&clone->base,
CAIRO_OPERATOR_SOURCE,
&pattern.base, NULL);
_cairo_pattern_fini (&pattern.base);
if (unlikely (status)) {
cairo_surface_destroy (&clone->base);
return (cairo_image_surface_t *) _cairo_surface_create_in_error (status);
return (cairo_image_surface_t *)_cairo_surface_create_in_error (status);
}
clone->base.device_transform =
surface->base.device_transform;
clone->base.device_transform_inverse =
surface->base.device_transform_inverse;
return clone;
}

View file

@ -2077,32 +2077,34 @@ static cairo_status_t
_trace_mask_to_path (cairo_image_surface_t *mask,
cairo_path_fixed_t *path)
{
cairo_status_t status;
cairo_image_surface_t *a1_mask;
uint8_t *row, *byte_ptr, byte;
const uint8_t *row;
int rows, cols, bytes_per_row;
int x, y, bit;
double xoff, yoff;
cairo_status_t status;
if (mask->format == CAIRO_FORMAT_A1)
a1_mask = (cairo_image_surface_t *) cairo_surface_reference (&mask->base);
else
a1_mask = _cairo_image_surface_clone (mask, CAIRO_FORMAT_A1);
status = cairo_surface_status (&a1_mask->base);
if (unlikely (status)) {
cairo_surface_destroy (&a1_mask->base);
mask = _cairo_image_surface_coerce (mask, CAIRO_FORMAT_A1);
status = mask->base.status;
if (unlikely (status))
return status;
}
cairo_surface_get_device_offset (&mask->base, &xoff, &yoff);
bytes_per_row = (a1_mask->width + 7) / 8;
for (y = 0, row = a1_mask->data, rows = a1_mask->height; rows; row += a1_mask->stride, rows--, y++) {
for (x = 0, byte_ptr = row, cols = bytes_per_row; cols; byte_ptr++, cols--) {
byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (*byte_ptr);
for (bit = 7; bit >= 0 && x < a1_mask->width; bit--, x++) {
if (byte & (1 << bit)) {
bytes_per_row = (mask->width + 7) / 8;
row = mask->data;
for (y = 0, rows = mask->height; rows--; row += mask->stride, y++) {
const uint8_t *byte_ptr = row;
x = 0;
for (cols = bytes_per_row; cols--; ) {
uint8_t byte = *byte_ptr++;
if (byte == 0) {
x += 8;
continue;
}
byte = CAIRO_BITSWAP8_IF_LITTLE_ENDIAN (byte);
for (bit = 1 << 7; bit && x < mask->width; bit >>= 1, x++) {
if (byte & bit) {
status = _add_unit_rectangle_to_path (path,
x - xoff, y - yoff);
if (unlikely (status))
@ -2113,7 +2115,7 @@ _trace_mask_to_path (cairo_image_surface_t *mask,
}
BAIL:
cairo_surface_destroy (&a1_mask->base);
cairo_surface_destroy (&mask->base);
return status;
}

View file

@ -657,8 +657,8 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
cairo_scaled_font_t *scaled_font,
unsigned long glyph_index)
{
cairo_image_surface_t *image;
cairo_scaled_glyph_t *scaled_glyph;
cairo_image_surface_t *image;
cairo_status_t status;
uint8_t *row, *byte;
int rows, cols;
@ -666,18 +666,17 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
status = _cairo_scaled_glyph_lookup (scaled_font,
glyph_index,
CAIRO_SCALED_GLYPH_INFO_METRICS|
CAIRO_SCALED_GLYPH_INFO_METRICS |
CAIRO_SCALED_GLYPH_INFO_SURFACE,
&scaled_glyph);
if (unlikely (status))
return status;
image = scaled_glyph->surface;
if (image->format != CAIRO_FORMAT_A1) {
image = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
if (cairo_surface_status (&image->base))
return cairo_surface_status (&image->base);
}
image = _cairo_image_surface_coerce (scaled_glyph->surface,
CAIRO_FORMAT_A1);
status = image->base.status;
if (unlikely (status))
return status;
_cairo_output_stream_printf (document->xml_node_glyphs, "<g");
_cairo_svg_surface_emit_transform (document->xml_node_glyphs, " transform",
@ -698,8 +697,7 @@ _cairo_svg_document_emit_bitmap_glyph_data (cairo_svg_document_t *document,
}
_cairo_output_stream_printf (document->xml_node_glyphs, "</g>\n");
if (image != scaled_glyph->surface)
cairo_surface_destroy (&image->base);
cairo_surface_destroy (&image->base);
return CAIRO_STATUS_SUCCESS;
}

View file

@ -87,18 +87,6 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
cairo_matrix_t *image_matrix)
{
cairo_status_t status;
cairo_image_surface_t *image_mask;
/* The only image type supported by Type 3 fonts are 1-bit image
* masks */
if (image->format == CAIRO_FORMAT_A1) {
image_mask = image;
} else {
image_mask = _cairo_image_surface_clone (image, CAIRO_FORMAT_A1);
status = cairo_surface_status (&image->base);
if (unlikely (status))
return status;
}
_cairo_output_stream_printf (surface->stream,
"q %f %f %f %f %f %f cm\n",
@ -109,14 +97,14 @@ _cairo_type3_glyph_surface_emit_image (cairo_type3_glyph_surface_t *surface,
image_matrix->x0,
image_matrix->y0);
status = surface->emit_image (image_mask, surface->stream);
/* The only image type supported by Type 3 fonts are 1-bit masks */
image = _cairo_image_surface_coerce (image, CAIRO_FORMAT_A1);
status = surface->emit_image (image, surface->stream);
cairo_surface_destroy (&image->base);
_cairo_output_stream_printf (surface->stream,
"Q\n");
if (image_mask != image)
cairo_surface_destroy (&image_mask->base);
return status;
}

View file

@ -2139,8 +2139,8 @@ _cairo_image_surface_set_clip_region (void *abstract_surface,
cairo_region_t *region);
cairo_private cairo_image_surface_t *
_cairo_image_surface_clone (cairo_image_surface_t *surface,
cairo_format_t format);
_cairo_image_surface_coerce (cairo_image_surface_t *surface,
cairo_format_t format);
cairo_private cairo_image_transparency_t
_cairo_image_analyze_transparency (cairo_image_surface_t *image);