[cairo-commit] 2 commits - src/cairo-xlib-surface.c
Carl Worth
cworth at kemper.freedesktop.org
Thu May 18 17:31:01 PDT 2006
src/cairo-xlib-surface.c | 295 ++++++++++++++++++++++++++---------------------
1 files changed, 168 insertions(+), 127 deletions(-)
New commits:
diff-tree 92a015ff8ec5c11aac6d9c0c6702fa4873c04381 (from 108431414faa8792659616bae35584b8fced3b21)
Author: Vladimir Vukicevic <vladimir at cyclone.vlad1.com>
Date: Mon Mar 27 13:49:58 2006 -0800
[xlib] only do glyph extents computation if non-solid source.
xlib_show_glyphs was always calculating the glyph extents, even when it
didn't need to; this only does it when necessary.
Also adds an implementation of surface_flush() for xlib that just calls
XSync.
(cherry picked from 8770ac5b5cdba8007c4c6a6a980e6e06acf6aeb6 commit)
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index df85239..2bf60ad 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1715,9 +1715,14 @@ _cairo_xlib_surface_get_font_options (vo
cairo_xlib_surface_t *surface = abstract_surface;
*options = surface->screen_info->font_options;
-
- if (_surface_has_alpha (surface) && options->antialias == CAIRO_ANTIALIAS_SUBPIXEL)
- options->antialias = CAIRO_ANTIALIAS_GRAY;
+}
+
+static cairo_status_t
+_cairo_xlib_surface_flush (void *abstract_surface)
+{
+ cairo_xlib_surface_t *surface = abstract_surface;
+ XSync (surface->dpy, False);
+ return CAIRO_STATUS_SUCCESS;
}
static void
@@ -1746,7 +1751,7 @@ static const cairo_surface_backend_t cai
_cairo_xlib_surface_get_extents,
NULL, /* old_show_glyphs */
_cairo_xlib_surface_get_font_options,
- NULL, /* flush */
+ _cairo_xlib_surface_flush,
NULL, /* mark_dirty_rectangle */
_cairo_xlib_surface_scaled_font_fini,
_cairo_xlib_surface_scaled_glyph_fini,
@@ -2571,8 +2576,6 @@ _cairo_xlib_surface_show_glyphs (void
cairo_scaled_glyph_t *scaled_glyph;
cairo_xlib_surface_font_private_t *font_private;
- cairo_rectangle_fixed_t glyph_extents;
-
int i;
unsigned long max_index = 0;
@@ -2617,13 +2620,6 @@ _cairo_xlib_surface_show_glyphs (void
(font_private != NULL && font_private->dpy != dst->dpy))
return CAIRO_INT_STATUS_UNSUPPORTED;
- status = _cairo_scaled_font_glyph_device_extents (scaled_font,
- glyphs,
- num_glyphs,
- &glyph_extents);
- if (status)
- return status;
-
/* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
* the mask (the glyphs). This code below was executed as a side effect
* of going through the _clip_and_composite fallback code for old_show_glyphs,
@@ -2635,11 +2631,28 @@ _cairo_xlib_surface_show_glyphs (void
op = CAIRO_OPERATOR_DEST_OUT;
}
- status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
- glyph_extents.x, glyph_extents.y,
- glyph_extents.width, glyph_extents.height,
- (cairo_surface_t **) &src,
- &attributes);
+ if (src_pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
+ status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+ 0, 0, 1, 1,
+ (cairo_surface_t **) &src,
+ &attributes);
+ } else {
+ cairo_rectangle_fixed_t glyph_extents;
+
+ status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+ glyphs,
+ num_glyphs,
+ &glyph_extents);
+ if (status)
+ return status;
+
+ status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+ glyph_extents.x, glyph_extents.y,
+ glyph_extents.width, glyph_extents.height,
+ (cairo_surface_t **) &src,
+ &attributes);
+ }
+
if (status)
goto FAIL;
diff-tree 108431414faa8792659616bae35584b8fced3b21 (from 3487191b2230571323201ed045263433e77e5345)
Author: Vladimir Vukicevic <vladimir at pobox.com>
Date: Wed Mar 8 21:08:57 2006 -0800
[xlib] implement _cairo_xlib_surface_show_glyphs
Avoid using the fallback paths as much as possible; implement real
show_glyphs, falling back for OPERATOR_SOURCE (due to Render bug), and all
unbounded operators (let the fallback code deal with fixup). Also fall
back if we have a fallback mask clip set.
(cherry picked from 3225a4ec820fd4051dd893ffc4258b182bd62dca commit)
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 3d528bf..df85239 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -40,6 +40,7 @@
#include "cairo-xlib-xrender.h"
#include "cairo-xlib-test.h"
#include "cairo-xlib-private.h"
+#include "cairo-clip-private.h"
#include <X11/extensions/Xrender.h>
#include <X11/extensions/renderproto.h>
@@ -64,6 +65,14 @@ _cairo_surface_is_xlib (cairo_surface_t
static cairo_bool_t
_native_byte_order_lsb (void);
+static cairo_int_status_t
+_cairo_xlib_surface_show_glyphs (void *abstract_dst,
+ cairo_operator_t op,
+ cairo_pattern_t *src_pattern,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font);
+
/*
* Instead of taking two round trips for each blending request,
* assume that if a particular drawable fails GetImage that it will
@@ -1711,20 +1720,6 @@ _cairo_xlib_surface_get_font_options (vo
options->antialias = CAIRO_ANTIALIAS_GRAY;
}
-static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
- cairo_operator_t op,
- cairo_pattern_t *pattern,
- void *abstract_surface,
- int source_x,
- int source_y,
- int dest_x,
- int dest_y,
- unsigned int width,
- unsigned int height,
- const cairo_glyph_t *glyphs,
- int num_glyphs);
-
static void
_cairo_xlib_surface_scaled_font_fini (cairo_scaled_font_t *scaled_font);
@@ -1749,12 +1744,19 @@ static const cairo_surface_backend_t cai
_cairo_xlib_surface_set_clip_region,
NULL, /* intersect_clip_path */
_cairo_xlib_surface_get_extents,
- _cairo_xlib_surface_old_show_glyphs,
+ NULL, /* old_show_glyphs */
_cairo_xlib_surface_get_font_options,
NULL, /* flush */
NULL, /* mark_dirty_rectangle */
_cairo_xlib_surface_scaled_font_fini,
_cairo_xlib_surface_scaled_glyph_fini,
+
+ NULL, /* paint */
+ NULL, /* mask */
+ NULL, /* stroke */
+ NULL, /* fill */
+ _cairo_xlib_surface_show_glyphs,
+ NULL /* snapshot */
};
/**
@@ -2363,14 +2365,13 @@ _cairo_xlib_surface_add_glyph (Display *
#define N_STACK_BUF 1024
static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs8 (cairo_scaled_font_t *scaled_font,
- cairo_operator_t op,
- cairo_xlib_surface_t *src,
- cairo_xlib_surface_t *self,
- int source_x,
- int source_y,
- const cairo_glyph_t *glyphs,
- int num_glyphs)
+_cairo_xlib_surface_show_glyphs8 (cairo_xlib_surface_t *dst,
+ cairo_operator_t op,
+ cairo_xlib_surface_t *src,
+ int src_x_offset, int src_y_offset,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt8 *elts = NULL;
@@ -2409,13 +2410,13 @@ _cairo_xlib_surface_old_show_glyphs8 (c
lastY = thisY;
}
- XRenderCompositeText8 (self->dpy,
+ XRenderCompositeText8 (dst->dpy,
_render_operator (op),
src->src_picture,
- self->dst_picture,
+ dst->dst_picture,
font_private->xrender_format,
- source_x + elts[0].xOff, source_y + elts[0].yOff,
- 0, 0,
+ src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+ elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@@ -2425,14 +2426,13 @@ _cairo_xlib_surface_old_show_glyphs8 (c
}
static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs16 (cairo_scaled_font_t *scaled_font,
- cairo_operator_t op,
- cairo_xlib_surface_t *src,
- cairo_xlib_surface_t *self,
- int source_x,
- int source_y,
- const cairo_glyph_t *glyphs,
- int num_glyphs)
+_cairo_xlib_surface_show_glyphs16 (cairo_xlib_surface_t *dst,
+ cairo_operator_t op,
+ cairo_xlib_surface_t *src,
+ int src_x_offset, int src_y_offset,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt16 *elts = NULL;
@@ -2471,13 +2471,13 @@ _cairo_xlib_surface_old_show_glyphs16 (c
lastY = thisY;
}
- XRenderCompositeText16 (self->dpy,
+ XRenderCompositeText16 (dst->dpy,
_render_operator (op),
src->src_picture,
- self->dst_picture,
+ dst->dst_picture,
font_private->xrender_format,
- source_x + elts[0].xOff, source_y + elts[0].yOff,
- 0, 0,
+ src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+ elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@@ -2487,14 +2487,13 @@ _cairo_xlib_surface_old_show_glyphs16 (c
}
static cairo_status_t
-_cairo_xlib_surface_old_show_glyphs32 (cairo_scaled_font_t *scaled_font,
- cairo_operator_t op,
- cairo_xlib_surface_t *src,
- cairo_xlib_surface_t *self,
- int source_x,
- int source_y,
- const cairo_glyph_t *glyphs,
- int num_glyphs)
+_cairo_xlib_surface_show_glyphs32 (cairo_xlib_surface_t *dst,
+ cairo_operator_t op,
+ cairo_xlib_surface_t *src,
+ int src_x_offset, int src_y_offset,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font)
{
cairo_xlib_surface_font_private_t *font_private = scaled_font->surface_private;
XGlyphElt32 *elts = NULL;
@@ -2533,13 +2532,13 @@ _cairo_xlib_surface_old_show_glyphs32 (c
lastY = thisY;
}
- XRenderCompositeText32 (self->dpy,
+ XRenderCompositeText32 (dst->dpy,
_render_operator (op),
src->src_picture,
- self->dst_picture,
+ dst->dst_picture,
font_private->xrender_format,
- source_x + elts[0].xOff, source_y + elts[0].yOff,
- 0, 0,
+ src_x_offset + elts[0].xOff, src_y_offset + elts[0].yOff,
+ elts[0].xOff, elts[0].yOff,
elts, num_glyphs);
if (elts != stack_elts)
@@ -2548,63 +2547,113 @@ _cairo_xlib_surface_old_show_glyphs32 (c
return CAIRO_STATUS_SUCCESS;
}
+typedef cairo_status_t (*cairo_xlib_surface_show_glyphs_func_t)
+ (cairo_xlib_surface_t *, cairo_operator_t, cairo_xlib_surface_t *, int, int,
+ const cairo_glyph_t *, int, cairo_scaled_font_t *);
+
static cairo_int_status_t
-_cairo_xlib_surface_old_show_glyphs (cairo_scaled_font_t *scaled_font,
- cairo_operator_t op,
- cairo_pattern_t *pattern,
- void *abstract_surface,
- int source_x,
- int source_y,
- int dest_x,
- int dest_y,
- unsigned int width,
- unsigned int height,
- const cairo_glyph_t *glyphs,
- int num_glyphs)
+_cairo_xlib_surface_show_glyphs (void *abstract_dst,
+ cairo_operator_t op,
+ cairo_pattern_t *src_pattern,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ cairo_scaled_font_t *scaled_font)
{
- cairo_surface_attributes_t attributes;
- cairo_int_status_t status;
- cairo_xlib_surface_t *self = abstract_surface;
- cairo_xlib_surface_t *src;
+ cairo_int_status_t status;
+ cairo_xlib_surface_t *dst = (cairo_xlib_surface_t*) abstract_dst;
+
+ composite_operation_t operation;
+ cairo_surface_attributes_t attributes;
+ cairo_xlib_surface_t *src = NULL;
+
const cairo_glyph_t *glyphs_chunk;
int glyphs_remaining, chunk_size, max_chunk_size;
- composite_operation_t operation;
cairo_scaled_glyph_t *scaled_glyph;
cairo_xlib_surface_font_private_t *font_private;
+
+ cairo_rectangle_fixed_t glyph_extents;
+
int i;
unsigned long max_index = 0;
-
- if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (self) || !self->xrender_format)
+
+ cairo_xlib_surface_show_glyphs_func_t show_glyphs_func;
+
+ cairo_pattern_union_t solid_pattern;
+
+ if (!CAIRO_SURFACE_RENDER_HAS_COMPOSITE_TEXT (dst) || !dst->xrender_format)
return CAIRO_INT_STATUS_UNSUPPORTED;
- operation = _categorize_composite_operation (self, op, pattern, TRUE);
+ /* Just let unbounded operators go through the fallback code
+ * instead of trying to do the fixups here */
+ if (!_cairo_operator_bounded_by_mask (op))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ /* Render <= 0.10 seems to have a bug with PictOpSrc and glyphs --
+ * the solid source seems to be multiplied by the glyph mask, and
+ * then the entire thing is copied to the destination surface,
+ * including the fully transparent "background" of the rectangular
+ * glyph surface. */
+ if (op == CAIRO_OPERATOR_SOURCE &&
+ !CAIRO_SURFACE_RENDER_AT_LEAST(dst, 0, 11))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ /* We can only use our code if we either have no clip or
+ * have a real native clip region set. If we're using
+ * fallback clip masking, we have to go through the full
+ * fallback path.
+ */
+ if (dst->base.clip &&
+ (dst->base.clip->mode != CAIRO_CLIP_MODE_REGION ||
+ dst->base.clip->surface != NULL))
+ return CAIRO_INT_STATUS_UNSUPPORTED;
+
+ operation = _categorize_composite_operation (dst, op, src_pattern, TRUE);
if (operation == DO_UNSUPPORTED)
return CAIRO_INT_STATUS_UNSUPPORTED;
-
+
font_private = scaled_font->surface_private;
if ((scaled_font->surface_backend != NULL &&
scaled_font->surface_backend != &cairo_xlib_surface_backend) ||
- (font_private != NULL && font_private->dpy != self->dpy))
+ (font_private != NULL && font_private->dpy != dst->dpy))
return CAIRO_INT_STATUS_UNSUPPORTED;
- status = _cairo_pattern_acquire_surface (pattern, &self->base,
- source_x, source_y, width, height,
- (cairo_surface_t **) &src,
- &attributes);
+ status = _cairo_scaled_font_glyph_device_extents (scaled_font,
+ glyphs,
+ num_glyphs,
+ &glyph_extents);
if (status)
- return status;
+ return status;
- operation = _recategorize_composite_operation (self, op, src, &attributes, TRUE);
+ /* PictOpClear doesn't seem to work with CompositeText; it seems to ignore
+ * the mask (the glyphs). This code below was executed as a side effect
+ * of going through the _clip_and_composite fallback code for old_show_glyphs,
+ * so PictOpClear was never used with CompositeText before.
+ */
+ if (op == CAIRO_OPERATOR_CLEAR) {
+ _cairo_pattern_init_solid (&solid_pattern.solid, CAIRO_COLOR_WHITE);
+ src_pattern = &solid_pattern.base;
+ op = CAIRO_OPERATOR_DEST_OUT;
+ }
+
+ status = _cairo_pattern_acquire_surface (src_pattern, &dst->base,
+ glyph_extents.x, glyph_extents.y,
+ glyph_extents.width, glyph_extents.height,
+ (cairo_surface_t **) &src,
+ &attributes);
+ if (status)
+ goto FAIL;
+
+ operation = _recategorize_composite_operation (dst, op, src, &attributes, TRUE);
if (operation == DO_UNSUPPORTED) {
status = CAIRO_INT_STATUS_UNSUPPORTED;
goto FAIL;
}
-
+
status = _cairo_xlib_surface_set_attributes (src, &attributes);
if (status)
- goto FAIL;
-
- /* Send all unsent glyphs to the server */
+ goto FAIL;
+
+ /* Send all unsent glyphs to the server, and count the max of the glyph indices */
for (i = 0; i < num_glyphs; i++) {
if (glyphs[i].index > max_index)
max_index = glyphs[i].index;
@@ -2615,20 +2664,24 @@ _cairo_xlib_surface_old_show_glyphs (cai
if (status != CAIRO_STATUS_SUCCESS)
return status;
if (scaled_glyph->surface_private == NULL) {
- _cairo_xlib_surface_add_glyph (self->dpy, scaled_font, scaled_glyph);
+ _cairo_xlib_surface_add_glyph (dst->dpy, scaled_font, scaled_glyph);
scaled_glyph->surface_private = (void *) 1;
}
}
-
- _cairo_xlib_surface_ensure_dst_picture (self);
- max_chunk_size = XMaxRequestSize (self->dpy);
- if (max_index < 256)
+ _cairo_xlib_surface_ensure_dst_picture (dst);
+
+ max_chunk_size = XMaxRequestSize (dst->dpy);
+ if (max_index < 256) {
max_chunk_size -= sz_xRenderCompositeGlyphs8Req;
- else if (max_index < 65536)
+ show_glyphs_func = _cairo_xlib_surface_show_glyphs8;
+ } else if (max_index < 65536) {
max_chunk_size -= sz_xRenderCompositeGlyphs16Req;
- else
+ show_glyphs_func = _cairo_xlib_surface_show_glyphs16;
+ } else {
max_chunk_size -= sz_xRenderCompositeGlyphs32Req;
+ show_glyphs_func = _cairo_xlib_surface_show_glyphs32;
+ }
max_chunk_size /= sz_xGlyphElt;
for (glyphs_remaining = num_glyphs, glyphs_chunk = glyphs;
@@ -2637,43 +2690,18 @@ _cairo_xlib_surface_old_show_glyphs (cai
{
chunk_size = MIN (glyphs_remaining, max_chunk_size);
- /* Call the appropriate sub-function. */
- if (max_index < 256)
- status = _cairo_xlib_surface_old_show_glyphs8 (scaled_font, op, src, self,
- source_x + attributes.x_offset - dest_x,
- source_y + attributes.y_offset - dest_y,
- glyphs_chunk, chunk_size);
- else if (max_index < 65536)
- status = _cairo_xlib_surface_old_show_glyphs16 (scaled_font, op, src, self,
- source_x + attributes.x_offset - dest_x,
- source_y + attributes.y_offset - dest_y,
- glyphs_chunk, chunk_size);
- else
- status = _cairo_xlib_surface_old_show_glyphs32 (scaled_font, op, src, self,
- source_x + attributes.x_offset - dest_x,
- source_y + attributes.y_offset - dest_y,
- glyphs_chunk, chunk_size);
+ status = show_glyphs_func (dst, op, src,
+ attributes.x_offset, attributes.y_offset,
+ glyphs_chunk, chunk_size, scaled_font);
if (status != CAIRO_STATUS_SUCCESS)
break;
}
- if (status == CAIRO_STATUS_SUCCESS && !_cairo_operator_bounded_by_mask (op)) {
- cairo_rectangle_fixed_t extents;
- status = _cairo_scaled_font_glyph_device_extents (scaled_font,
- glyphs,
- num_glyphs,
- &extents);
- if (status == CAIRO_STATUS_SUCCESS)
- status = _cairo_surface_composite_shape_fixup_unbounded
- (&self->base, &attributes, src->width, src->height,
- extents.width, extents.height,
- source_x, source_y,
- dest_x - extents.x, dest_y - extents.y,
- dest_x, dest_y,
- width, height);
- }
- FAIL:
- _cairo_pattern_release_surface (pattern, &src->base, &attributes);
-
+ FAIL:
+ if (src)
+ _cairo_pattern_release_surface (src_pattern, &src->base, &attributes);
+ if (src_pattern == &solid_pattern.base)
+ _cairo_pattern_fini (&solid_pattern.base);
return status;
}
+
More information about the cairo-commit
mailing list