mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 02:58:02 +02:00
[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:
parent
9b46d13b6c
commit
6458903c95
5 changed files with 59 additions and 65 deletions
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue