mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-05-05 18:08:03 +02:00
[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:
parent
6e78409417
commit
6960162c5e
3 changed files with 65 additions and 0 deletions
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue