diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-04-30 12:02:38 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2012-04-30 12:02:38 -0400 |
commit | af3c8abbce529b0928742cc219e5e8e21191eee7 (patch) | |
tree | befb7c0e7c29f4f1b26264104a6e391701b66b16 | |
parent | 752c3b69e008b7d219da8cc5c657cf995732d3b8 (diff) |
Revert "Use pixman glyphs"
This was pushed accidentally - apologies.
This reverts commit 752c3b69e008b7d219da8cc5c657cf995732d3b8.
-rw-r--r-- | src/cairo-image-compositor.c | 313 | ||||
-rw-r--r-- | src/cairo-mutex-list-private.h | 1 | ||||
-rw-r--r-- | src/cairo-scaled-font.c | 2 | ||||
-rw-r--r-- | src/cairoint.h | 4 |
4 files changed, 212 insertions, 108 deletions
diff --git a/src/cairo-image-compositor.c b/src/cairo-image-compositor.c index 047fbb1f..5a1ea4a6 100644 --- a/src/cairo-image-compositor.c +++ b/src/cairo-image-compositor.c @@ -750,37 +750,187 @@ composite_tristrip (void *_dst, return CAIRO_STATUS_SUCCESS; } -static pixman_glyph_cache_t *global_glyph_cache; - -static inline pixman_glyph_cache_t * -get_glyph_cache (void) +static cairo_int_status_t +check_composite_glyphs (const cairo_composite_rectangles_t *extents, + cairo_scaled_font_t *scaled_font, + cairo_glyph_t *glyphs, + int *num_glyphs) { - if (!global_glyph_cache) - global_glyph_cache = pixman_glyph_cache_create (); - - return global_glyph_cache; + return CAIRO_STATUS_SUCCESS; } -void -_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph) +static cairo_int_status_t +composite_one_glyph (void *_dst, + cairo_operator_t op, + cairo_surface_t *_src, + int src_x, + int src_y, + int dst_x, + int dst_y, + cairo_composite_glyphs_info_t *info) { - CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex); + cairo_image_surface_t *glyph_surface; + cairo_scaled_glyph_t *scaled_glyph; + cairo_status_t status; + int x, y; - if (global_glyph_cache) { - pixman_glyph_cache_remove ( - global_glyph_cache, scaled_font, (void *)_cairo_scaled_glyph_index (scaled_glyph)); - } + TRACE ((stderr, "%s\n", __FUNCTION__)); + + status = _cairo_scaled_glyph_lookup (info->font, + info->glyphs[0].index, + CAIRO_SCALED_GLYPH_INFO_SURFACE, + &scaled_glyph); + + if (unlikely (status)) + return status; + + glyph_surface = scaled_glyph->surface; + if (glyph_surface->width == 0 || glyph_surface->height == 0) + return CAIRO_INT_STATUS_NOTHING_TO_DO; + + /* round glyph locations to the nearest pixel */ + /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ + x = _cairo_lround (info->glyphs[0].x - + glyph_surface->base.device_transform.x0); + y = _cairo_lround (info->glyphs[0].y - + glyph_surface->base.device_transform.y0); + + pixman_image_composite32 (_pixman_operator (op), + ((cairo_image_source_t *)_src)->pixman_image, + glyph_surface->pixman_image, + to_pixman_image (_dst), + x + src_x, y + src_y, + 0, 0, + x - dst_x, y - dst_y, + glyph_surface->width, + glyph_surface->height); - CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); + return CAIRO_INT_STATUS_SUCCESS; } static cairo_int_status_t -check_composite_glyphs (const cairo_composite_rectangles_t *extents, - cairo_scaled_font_t *scaled_font, - cairo_glyph_t *glyphs, - int *num_glyphs) +composite_glyphs_via_mask (void *_dst, + cairo_operator_t op, + cairo_surface_t *_src, + int src_x, + int src_y, + int dst_x, + int dst_y, + cairo_composite_glyphs_info_t *info) { + cairo_scaled_glyph_t *glyph_cache[64]; + cairo_bool_t component_alpha = FALSE; + uint8_t buf[2048]; + pixman_image_t *mask; + cairo_status_t status; + int i; + + TRACE ((stderr, "%s\n", __FUNCTION__)); + + /* XXX convert the glyphs to common formats a8/a8r8g8b8 to hit + * optimised paths through pixman. Should we increase the bit + * depth of the target surface, we should reconsider the appropriate + * mask formats. + */ + i = (info->extents.width + 3) & ~3; + if (i * info->extents.height > (int) sizeof (buf)) { + mask = pixman_image_create_bits (PIXMAN_a8, + info->extents.width, + info->extents.height, + NULL, 0); + } else { + memset (buf, 0, i * info->extents.height); + mask = pixman_image_create_bits (PIXMAN_a8, + info->extents.width, + info->extents.height, + (uint32_t *)buf, i); + } + if (unlikely (mask == NULL)) + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + + memset (glyph_cache, 0, sizeof (glyph_cache)); + status = CAIRO_STATUS_SUCCESS; + + for (i = 0; i < info->num_glyphs; i++) { + cairo_image_surface_t *glyph_surface; + cairo_scaled_glyph_t *scaled_glyph; + unsigned long glyph_index = info->glyphs[i].index; + int cache_index = glyph_index % ARRAY_LENGTH (glyph_cache); + int x, y; + + scaled_glyph = glyph_cache[cache_index]; + if (scaled_glyph == NULL || + _cairo_scaled_glyph_index (scaled_glyph) != glyph_index) + { + status = _cairo_scaled_glyph_lookup (info->font, glyph_index, + CAIRO_SCALED_GLYPH_INFO_SURFACE, + &scaled_glyph); + + if (unlikely (status)) { + pixman_image_unref (mask); + return status; + } + + glyph_cache[cache_index] = scaled_glyph; + } + + glyph_surface = scaled_glyph->surface; + if (glyph_surface->width && glyph_surface->height) { + if (glyph_surface->base.content & CAIRO_CONTENT_COLOR && + ! component_alpha) { + pixman_image_t *ca_mask; + + ca_mask = pixman_image_create_bits (PIXMAN_a8r8g8b8, + info->extents.width, + info->extents.height, + NULL, 0); + if (unlikely (ca_mask == NULL)) { + pixman_image_unref (mask); + return _cairo_error (CAIRO_STATUS_NO_MEMORY); + } + + pixman_image_composite32 (PIXMAN_OP_SRC, + mask, 0, ca_mask, + 0, 0, + 0, 0, + 0, 0, + info->extents.width, + info->extents.height); + pixman_image_unref (mask); + mask = ca_mask; + component_alpha = TRUE; + } + + /* round glyph locations to the nearest pixel */ + /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ + x = _cairo_lround (info->glyphs[i].x - + glyph_surface->base.device_transform.x0); + y = _cairo_lround (info->glyphs[i].y - + glyph_surface->base.device_transform.y0); + + pixman_image_composite32 (PIXMAN_OP_ADD, + glyph_surface->pixman_image, NULL, mask, + 0, 0, + 0, 0, + x - info->extents.x, y - info->extents.y, + glyph_surface->width, + glyph_surface->height); + } + } + + if (component_alpha) + pixman_image_set_component_alpha (mask, TRUE); + + pixman_image_composite32 (_pixman_operator (op), + ((cairo_image_source_t *)_src)->pixman_image, + mask, + to_pixman_image (_dst), + info->extents.x + src_x, info->extents.y + src_y, + 0, 0, + info->extents.x - dst_x, info->extents.y - dst_y, + info->extents.width, info->extents.height); + pixman_image_unref (mask); + return CAIRO_STATUS_SUCCESS; } @@ -794,104 +944,65 @@ composite_glyphs (void *_dst, int dst_y, cairo_composite_glyphs_info_t *info) { + cairo_scaled_glyph_t *glyph_cache[64]; + pixman_image_t *dst, *src; cairo_status_t status; - pixman_glyph_cache_t *glyph_cache; - pixman_glyph_t pglyphs_stack[CAIRO_STACK_ARRAY_LENGTH (pixman_glyph_t)]; - pixman_glyph_t *pglyphs = pglyphs_stack; - pixman_format_code_t mask_format = 0; - pixman_glyph_t *pg; int i; TRACE ((stderr, "%s\n", __FUNCTION__)); - CAIRO_MUTEX_LOCK (_cairo_glyph_cache_mutex); + if (info->num_glyphs == 1) + return composite_one_glyph(_dst, op, _src, src_x, src_y, dst_x, dst_y, info); - glyph_cache = get_glyph_cache(); + if (info->use_mask) + return composite_glyphs_via_mask(_dst, op, _src, src_x, src_y, dst_x, dst_y, info); - if (unlikely (!glyph_cache)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto out_no_glyph_cache; - } + op = _pixman_operator (op); + dst = to_pixman_image (_dst); + src = ((cairo_image_source_t *)_src)->pixman_image; - pixman_glyph_cache_freeze (glyph_cache); - - if (info->num_glyphs > ARRAY_LENGTH (pglyphs_stack)) { - pglyphs = _cairo_malloc_ab (info->num_glyphs, sizeof (pixman_glyph_t)); + memset (glyph_cache, 0, sizeof (glyph_cache)); + status = CAIRO_STATUS_SUCCESS; - if (unlikely (!pglyphs)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - goto out; - } - } - - if (unlikely (!glyph_cache)) - return _cairo_error (CAIRO_STATUS_NO_MEMORY); - - pg = pglyphs; for (i = 0; i < info->num_glyphs; i++) { - unsigned long index = info->glyphs[i].index; - const void *glyph; - - glyph = pixman_glyph_cache_contains (glyph_cache, info->font, (void *)index); - if (!glyph || !mask_format) { - cairo_scaled_glyph_t *scaled_glyph; - cairo_image_surface_t *glyph_surface; - - status = _cairo_scaled_glyph_lookup (info->font, index, + int x, y; + cairo_image_surface_t *glyph_surface; + cairo_scaled_glyph_t *scaled_glyph; + unsigned long glyph_index = info->glyphs[i].index; + int cache_index = glyph_index % ARRAY_LENGTH (glyph_cache); + + scaled_glyph = glyph_cache[cache_index]; + if (scaled_glyph == NULL || + _cairo_scaled_glyph_index (scaled_glyph) != glyph_index) + { + status = _cairo_scaled_glyph_lookup (info->font, glyph_index, CAIRO_SCALED_GLYPH_INFO_SURFACE, &scaled_glyph); + if (unlikely (status)) - goto out; - - glyph_surface = scaled_glyph->surface; - - if (!glyph) { - glyph = pixman_glyph_cache_insert (glyph_cache, info->font, (void *)index, - glyph_surface->base.device_transform.x0, - glyph_surface->base.device_transform.y0, - glyph_surface->pixman_image); - if (unlikely (!glyph)) { - status = _cairo_error (CAIRO_STATUS_NO_MEMORY); - - goto out; - } - } + break; - if (!mask_format) - mask_format = pixman_image_get_format (glyph_surface->pixman_image); + glyph_cache[cache_index] = scaled_glyph; } - - pg->x = info->glyphs[i].x; - pg->y = info->glyphs[i].y; - pg->glyph = glyph; - pg++; - } - if (info->use_mask) - { - pixman_composite_glyphs (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - to_pixman_image (_dst), - mask_format, - src_x, src_y, - dst_x, dst_y, - glyph_cache, pg - pglyphs, pglyphs); - } - else - { - pixman_composite_glyphs_no_mask (_pixman_operator (op), - ((cairo_image_source_t *)_src)->pixman_image, - to_pixman_image (_dst), - src_x, src_y, - dst_x, dst_y, - glyph_cache, pg - pglyphs, pglyphs); + glyph_surface = scaled_glyph->surface; + if (glyph_surface->width && glyph_surface->height) { + /* round glyph locations to the nearest pixel */ + /* XXX: FRAGILE: We're ignoring device_transform scaling here. A bug? */ + x = _cairo_lround (info->glyphs[i].x - + glyph_surface->base.device_transform.x0); + y = _cairo_lround (info->glyphs[i].y - + glyph_surface->base.device_transform.y0); + + pixman_image_composite32 (op, src, glyph_surface->pixman_image, dst, + x + src_x, y + src_y, + 0, 0, + x - dst_x, y - dst_y, + glyph_surface->width, + glyph_surface->height); + } } -out: - pixman_glyph_cache_freeze (glyph_cache); -out_no_glyph_cache: - CAIRO_MUTEX_UNLOCK (_cairo_glyph_cache_mutex); - return status; } diff --git a/src/cairo-mutex-list-private.h b/src/cairo-mutex-list-private.h index f46afadb..4016f8e5 100644 --- a/src/cairo-mutex-list-private.h +++ b/src/cairo-mutex-list-private.h @@ -45,7 +45,6 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_string_mutex) CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex) CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex) CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex) -CAIRO_MUTEX_DECLARE (_cairo_glyph_cache_mutex) #if CAIRO_HAS_FT_FONT CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex) diff --git a/src/cairo-scaled-font.c b/src/cairo-scaled-font.c index 2a489789..59440b2c 100644 --- a/src/cairo-scaled-font.c +++ b/src/cairo-scaled-font.c @@ -212,8 +212,6 @@ _cairo_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, private->destroy (private, scaled_glyph, scaled_font); } - _cairo_image_scaled_glyph_fini (scaled_font, scaled_glyph); - if (scaled_glyph->surface != NULL) cairo_surface_destroy (&scaled_glyph->surface->base); diff --git a/src/cairoint.h b/src/cairoint.h index 22fd2480..9f20d517 100644 --- a/src/cairoint.h +++ b/src/cairoint.h @@ -1484,10 +1484,6 @@ _pixman_format_to_masks (pixman_format_code_t pixman_format, cairo_format_masks_t *masks); cairo_private void -_cairo_image_scaled_glyph_fini (cairo_scaled_font_t *scaled_font, - cairo_scaled_glyph_t *scaled_glyph); - -cairo_private void _cairo_image_reset_static_data (void); cairo_private cairo_surface_t * |