[xlib] Discard clip if larger than glyph extents

Implement cheap calculation of glyph extents to see whether we can discard
the clip region. This is effective around 50% of the time for firefox (and
makes the xtrace so much neater).
This commit is contained in:
Chris Wilson 2009-09-11 14:56:17 +01:00
parent 6e78409417
commit 6960162c5e
3 changed files with 65 additions and 0 deletions

View file

@ -2021,6 +2021,42 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
return CAIRO_STATUS_SUCCESS;
}
void
_cairo_scaled_font_glyph_approximate_extents (cairo_scaled_font_t *scaled_font,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_rectangle_int_t *extents)
{
double x0 = HUGE_VAL, x1 = -HUGE_VAL;
double y0 = HUGE_VAL, y1 = -HUGE_VAL;
int i;
for (i = 0; i < num_glyphs; i++) {
double g;
g = glyphs[i].x;
if (g < x0) x0 = g;
if (g > x1) x1 = g;
g = glyphs[i].y;
if (g < y0) y0 = g;
if (g > y1) y1 = g;
}
if (x0 <= x1 && y0 <= y1) {
extents->x = floor (x0 - scaled_font->extents.max_x_advance);
extents->width = ceil (x1 + scaled_font->extents.max_x_advance);
extents->width -= extents->x;
extents->y = floor (y0 - scaled_font->extents.ascent);
extents->height = ceil (y1 + scaled_font->extents.descent);
extents->height -= extents->y;
} else {
extents->x = extents->y = 0;
extents->width = extents->height = 0;
}
}
cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,

View file

@ -4413,6 +4413,29 @@ _cairo_xlib_surface_show_glyphs (void *abstract_dst,
if (! _cairo_xlib_surface_owns_font (dst, scaled_font))
return UNSUPPORTED ("unowned font");
if (clip_region != NULL &&
cairo_region_num_rectangles (clip_region) == 1)
{
cairo_rectangle_int_t glyph_extents;
const cairo_rectangle_int_t *clip_extents;
/* Can we do without the clip?
* Around 50% of the time the clip is redundant (firefox).
*/
_cairo_scaled_font_glyph_approximate_extents (scaled_font,
glyphs, num_glyphs,
&glyph_extents);
clip_extents = &clip->path->extents;
if (clip_extents->x <= glyph_extents.x &&
clip_extents->y <= glyph_extents.y &&
clip_extents->x + clip_extents->width >= glyph_extents.x + glyph_extents.width &&
clip_extents->y + clip_extents->height >= glyph_extents.y + glyph_extents.height)
{
clip_region = NULL;
}
}
status = _cairo_xlib_surface_set_clip_region (dst, clip_region);
if (unlikely (status))
return status;

View file

@ -1726,6 +1726,12 @@ _cairo_scaled_font_glyph_device_extents (cairo_scaled_font_t *scaled_font,
cairo_rectangle_int_t *extents,
cairo_bool_t *overlap);
cairo_private void
_cairo_scaled_font_glyph_approximate_extents (cairo_scaled_font_t *scaled_font,
const cairo_glyph_t *glyphs,
int num_glyphs,
cairo_rectangle_int_t *extents);
cairo_private cairo_status_t
_cairo_scaled_font_show_glyphs (cairo_scaled_font_t *scaled_font,
cairo_operator_t op,