[cairo-commit] Branch '1.8' - 3 commits - AUTHORS perf/cairo-perf-diff src/cairo-gstate.c src/cairo-xcb-surface.c
Chris Wilson
ickle at kemper.freedesktop.org
Sun Dec 14 03:15:03 PST 2008
AUTHORS | 1
perf/cairo-perf-diff | 2
src/cairo-gstate.c | 223 +++++++++++++++++++++++++++++++++++++-----------
src/cairo-xcb-surface.c | 8 +
4 files changed, 184 insertions(+), 50 deletions(-)
New commits:
commit 79bd32a6ccb1a882ddd2b1585ab155f568bf5ec7
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Sat Dec 6 13:32:37 2008 +0200
[perf-diff] Fix cairo-perf-diff for git 1.6
Since git 1.6 the plumbing commands aren't installed in the user's
path by default. This patch fixes cairo-perf-diff to find the
git-sh-setup command from git's lib dir.
(cherry picked from commit 0c0f4862c52d68776024f125b003ade455044b27)
diff --git a/perf/cairo-perf-diff b/perf/cairo-perf-diff
index 50cd1f2..718cdc5 100755
--- a/perf/cairo-perf-diff
+++ b/perf/cairo-perf-diff
@@ -89,7 +89,7 @@ fi
git_setup() {
SUBDIRECTORY_OK='Yes'
- . git-sh-setup
+ . "$(git --exec-path)/git-sh-setup"
CAIRO_DIR=`dirname $GIT_DIR`
if [ "$CAIRO_DIR" = "." ]; then
CAIRO_DIR=`pwd`
commit 97b5240beeb9206f4dbda6ffce33b51aa16eec2f
Author: Julien Danjou <julien at danjou.info>
Date: Tue Nov 18 10:01:49 2008 +0100
[xcb] check for render extension presence
Otherwise this may leads to an invalid memory access to r.
Fixes: Bug 18588 - XCB backend fails with missing render.
https://bugs.freedesktop.org/show_bug.cgi?id=18588
Signed-off-by: Julien Danjou <julien at danjou.info>
Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
(cherry picked from commit 834f1d7b7097dcc3a32f6c65d21e87fd272d924a)
diff --git a/AUTHORS b/AUTHORS
index 488f4c0..289fecb 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -16,6 +16,7 @@ Steve Chaplin <stevech1097 at yahoo.com.au> Bug fixes for PNG reading
Tomasz Cholewo <cholewo at ieee-cis.org> Bug fixes
Manu Cornet <manu at manucornet.net> SVG build fix
Frederic Crozat <fcrozat at mandriva.com> Fix test suite for OPD platforms (IA64 or PPC64)
+Julien Danjou <julien at danjou.info> XCB fixes
Radek DoulÃk <rodo at novell.com> Bug report and test case
John Ehresman <jpe at wingide.com> Build fixes for win32
John Ellson <ellson at research.att.com> First font/glyph extents functions
diff --git a/src/cairo-xcb-surface.c b/src/cairo-xcb-surface.c
index 9b7eb4b..c63e851 100644
--- a/src/cairo-xcb-surface.c
+++ b/src/cairo-xcb-surface.c
@@ -1732,7 +1732,8 @@ _cairo_xcb_surface_create_internal (xcb_connection_t *dpy,
int depth)
{
cairo_xcb_surface_t *surface;
- const xcb_render_query_version_reply_t *r;
+ const xcb_query_extension_reply_t *er;
+ const xcb_render_query_version_reply_t *r = NULL;
surface = malloc (sizeof (cairo_xcb_surface_t));
if (surface == NULL)
@@ -1764,7 +1765,10 @@ _cairo_xcb_surface_create_internal (xcb_connection_t *dpy,
;
}
- r = xcb_render_util_query_version(dpy);
+ er = xcb_get_extension_data(dpy, &xcb_render_id);
+ if(er && er->present) {
+ r = xcb_render_util_query_version(dpy);
+ }
if (r) {
surface->render_major = r->major_version;
surface->render_minor = r->minor_version;
commit 6fed98c0d3b0708ad5171654179a482fa7d88805
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Dec 5 21:14:45 2008 +0000
[gstate] Remove culled glyphs from clusters.
Sascha Steinbiss reported a bug where the PDF backend was reading beyond
the end of the glyph array:
http://lists.cairographics.org/archives/cairo/2008-December/015976.html.
It transpires that in the early glyph culling in the gstate we were
not updating the clusters to skip culled glyphs.
diff --git a/src/cairo-gstate.c b/src/cairo-gstate.c
index fe8d279..28a9538 100644
--- a/src/cairo-gstate.c
+++ b/src/cairo-gstate.c
@@ -64,8 +64,12 @@ static cairo_status_t
_cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
const cairo_glyph_t *glyphs,
int num_glyphs,
+ const cairo_text_cluster_t *clusters,
+ int num_clusters,
+ cairo_text_cluster_flags_t cluster_flags,
cairo_glyph_t *transformed_glyphs,
- int *num_transformed_glyphs);
+ int *num_transformed_glyphs,
+ cairo_text_cluster_t *transformed_clusters);
cairo_status_t
_cairo_gstate_init (cairo_gstate_t *gstate,
@@ -1581,10 +1585,12 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
int num_clusters,
cairo_text_cluster_flags_t cluster_flags)
{
- cairo_status_t status;
cairo_pattern_union_t source_pattern;
- cairo_glyph_t *transformed_glyphs;
cairo_glyph_t stack_transformed_glyphs[CAIRO_STACK_ARRAY_LENGTH (cairo_glyph_t)];
+ cairo_glyph_t *transformed_glyphs;
+ cairo_text_cluster_t stack_transformed_clusters[CAIRO_STACK_ARRAY_LENGTH (cairo_text_cluster_t)];
+ cairo_text_cluster_t *transformed_clusters;
+ cairo_status_t status;
if (gstate->source->status)
return gstate->source->status;
@@ -1597,18 +1603,37 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (status)
return status;
- if (num_glyphs <= ARRAY_LENGTH (stack_transformed_glyphs)) {
- transformed_glyphs = stack_transformed_glyphs;
- } else {
+ transformed_glyphs = stack_transformed_glyphs;
+ transformed_clusters = stack_transformed_clusters;
+
+ if (num_glyphs > ARRAY_LENGTH (stack_transformed_glyphs)) {
transformed_glyphs = cairo_glyph_allocate (num_glyphs);
- if (transformed_glyphs == NULL)
- return _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ if (transformed_glyphs == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto CLEANUP_GLYPHS;
+ }
+ }
+
+ /* Just in case */
+ if (!clusters)
+ num_clusters = 0;
+
+ if (num_clusters > ARRAY_LENGTH (stack_transformed_clusters)) {
+ transformed_clusters = cairo_text_cluster_allocate (num_clusters);
+ if (transformed_clusters == NULL) {
+ status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
+ goto CLEANUP_GLYPHS;
+ }
}
status = _cairo_gstate_transform_glyphs_to_backend (gstate,
glyphs, num_glyphs,
+ clusters,
+ num_clusters,
+ cluster_flags,
transformed_glyphs,
- &num_glyphs);
+ &num_glyphs,
+ transformed_clusters);
if (status || num_glyphs == 0)
goto CLEANUP_GLYPHS;
@@ -1617,10 +1642,6 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
if (status)
goto CLEANUP_GLYPHS;
- /* Just in case */
- if (!clusters)
- num_clusters = 0;
-
/* For really huge font sizes, we can just do path;fill instead of
* show_glyphs, as show_glyphs would put excess pressure on the cache,
* and moreover, not all components below us correctly handle huge font
@@ -1638,7 +1659,7 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
&source_pattern.base,
utf8, utf8_len,
transformed_glyphs, num_glyphs,
- clusters, num_clusters,
+ transformed_clusters, num_clusters,
cluster_flags,
gstate->scaled_font);
} else {
@@ -1667,6 +1688,8 @@ _cairo_gstate_show_text_glyphs (cairo_gstate_t *gstate,
CLEANUP_GLYPHS:
if (transformed_glyphs != stack_transformed_glyphs)
cairo_glyph_free (transformed_glyphs);
+ if (transformed_clusters != stack_transformed_clusters)
+ cairo_text_cluster_free (transformed_clusters);
return status;
}
@@ -1694,8 +1717,9 @@ _cairo_gstate_glyph_path (cairo_gstate_t *gstate,
status = _cairo_gstate_transform_glyphs_to_backend (gstate,
glyphs, num_glyphs,
+ NULL, 0, 0,
transformed_glyphs,
- NULL);
+ NULL, NULL);
if (status)
goto CLEANUP_GLYPHS;
@@ -1744,13 +1768,17 @@ _cairo_gstate_get_antialias (cairo_gstate_t *gstate)
* cull/drop glyphs that will not be visible.
**/
static cairo_status_t
-_cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
- const cairo_glyph_t *glyphs,
- int num_glyphs,
- cairo_glyph_t *transformed_glyphs,
- int *num_transformed_glyphs)
-{
- int i, j;
+_cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
+ const cairo_glyph_t *glyphs,
+ int num_glyphs,
+ const cairo_text_cluster_t *clusters,
+ int num_clusters,
+ cairo_text_cluster_flags_t cluster_flags,
+ cairo_glyph_t *transformed_glyphs,
+ int *num_transformed_glyphs,
+ cairo_text_cluster_t *transformed_clusters)
+{
+ int i, j, k;
cairo_matrix_t *ctm = &gstate->ctm;
cairo_matrix_t *font_matrix = &gstate->font_matrix;
cairo_matrix_t *device_transform = &gstate->target->device_transform;
@@ -1796,22 +1824,52 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
#define KEEP_GLYPH(glyph) (x1 <= glyph.x && glyph.x <= x2 && y1 <= glyph.y && glyph.y <= y2)
+ j = 0;
if (_cairo_matrix_is_identity (ctm) &&
_cairo_matrix_is_identity (device_transform) &&
font_matrix->x0 == 0 && font_matrix->y0 == 0)
{
- if (!drop)
- memcpy (transformed_glyphs, glyphs, num_glyphs * sizeof (cairo_glyph_t));
- else {
- for (j = 0, i = 0; i < num_glyphs; i++)
- {
+ if (! drop) {
+ memcpy (transformed_glyphs, glyphs,
+ num_glyphs * sizeof (cairo_glyph_t));
+ } else if (num_clusters == 0) {
+ for (i = 0; i < num_glyphs; i++) {
transformed_glyphs[j].index = glyphs[i].index;
transformed_glyphs[j].x = glyphs[i].x;
transformed_glyphs[j].y = glyphs[i].y;
if (KEEP_GLYPH (transformed_glyphs[j]))
j++;
}
- *num_transformed_glyphs = j;
+ } else {
+ const cairo_glyph_t *cur_glyph;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph = glyphs + num_glyphs - 1;
+ else
+ cur_glyph = glyphs;
+
+ for (i = 0; i < num_clusters; i++) {
+ cairo_bool_t cluster_visible = FALSE;
+
+ for (k = 0; k < clusters[i].num_glyphs; k++) {
+ transformed_glyphs[j+k].index = cur_glyph->index;
+ transformed_glyphs[j+k].x = cur_glyph->x;
+ transformed_glyphs[j+k].y = cur_glyph->y;
+ if (KEEP_GLYPH (transformed_glyphs[j+k]))
+ cluster_visible = TRUE;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph--;
+ else
+ cur_glyph++;
+ }
+
+ transformed_clusters[i] = clusters[i];
+ if (cluster_visible)
+ j += k;
+ else
+ transformed_clusters[i].num_glyphs = 0;
+ }
}
}
else if (_cairo_matrix_is_translation (ctm) &&
@@ -1820,15 +1878,45 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
double tx = font_matrix->x0 + ctm->x0 + device_transform->x0;
double ty = font_matrix->y0 + ctm->y0 + device_transform->y0;
- for (j = 0, i = 0; i < num_glyphs; i++)
- {
- transformed_glyphs[j].index = glyphs[i].index;
- transformed_glyphs[j].x = glyphs[i].x + tx;
- transformed_glyphs[j].y = glyphs[i].y + ty;
- if (!drop || KEEP_GLYPH (transformed_glyphs[j]))
- j++;
- }
- *num_transformed_glyphs = j;
+ if (! drop || num_clusters == 0) {
+ for (i = 0; i < num_glyphs; i++) {
+ transformed_glyphs[j].index = glyphs[i].index;
+ transformed_glyphs[j].x = glyphs[i].x + tx;
+ transformed_glyphs[j].y = glyphs[i].y + ty;
+ if (!drop || KEEP_GLYPH (transformed_glyphs[j]))
+ j++;
+ }
+ } else {
+ const cairo_glyph_t *cur_glyph;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph = glyphs + num_glyphs - 1;
+ else
+ cur_glyph = glyphs;
+
+ for (i = 0; i < num_clusters; i++) {
+ cairo_bool_t cluster_visible = FALSE;
+
+ for (k = 0; k < clusters[i].num_glyphs; k++) {
+ transformed_glyphs[j+k].index = cur_glyph->index;
+ transformed_glyphs[j+k].x = cur_glyph->x + tx;
+ transformed_glyphs[j+k].y = cur_glyph->y + ty;
+ if (KEEP_GLYPH (transformed_glyphs[j+k]))
+ cluster_visible = TRUE;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph--;
+ else
+ cur_glyph++;
+ }
+
+ transformed_clusters[i] = clusters[i];
+ if (cluster_visible)
+ j += k;
+ else
+ transformed_clusters[i].num_glyphs = 0;
+ }
+ }
}
else
{
@@ -1842,16 +1930,57 @@ _cairo_gstate_transform_glyphs_to_backend (cairo_gstate_t *gstate,
cairo_matrix_multiply (&aggregate_transform,
&aggregate_transform, device_transform);
- for (j = 0, i = 0; i < num_glyphs; i++)
- {
- transformed_glyphs[j] = glyphs[i];
- cairo_matrix_transform_point (&aggregate_transform,
- &transformed_glyphs[j].x,
- &transformed_glyphs[j].y);
- if (!drop || KEEP_GLYPH (transformed_glyphs[j]))
- j++;
- }
- *num_transformed_glyphs = j;
+ if (! drop || num_clusters == 0) {
+ for (i = 0; i < num_glyphs; i++) {
+ transformed_glyphs[j] = glyphs[i];
+ cairo_matrix_transform_point (&aggregate_transform,
+ &transformed_glyphs[j].x,
+ &transformed_glyphs[j].y);
+ if (! drop || KEEP_GLYPH (transformed_glyphs[j]))
+ j++;
+ }
+ } else {
+ const cairo_glyph_t *cur_glyph;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph = glyphs + num_glyphs - 1;
+ else
+ cur_glyph = glyphs;
+
+ for (i = 0; i < num_clusters; i++) {
+ cairo_bool_t cluster_visible = FALSE;
+ for (k = 0; k < clusters[i].num_glyphs; k++) {
+ transformed_glyphs[j+k] = *cur_glyph;
+ cairo_matrix_transform_point (&aggregate_transform,
+ &transformed_glyphs[j+k].x,
+ &transformed_glyphs[j+k].y);
+ if (KEEP_GLYPH (transformed_glyphs[j+k]))
+ cluster_visible = TRUE;
+
+ if (cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD)
+ cur_glyph--;
+ else
+ cur_glyph++;
+ }
+
+ transformed_clusters[i] = clusters[i];
+ if (cluster_visible)
+ j += k;
+ else
+ transformed_clusters[i].num_glyphs = 0;
+ }
+ }
+ }
+ *num_transformed_glyphs = j;
+
+ if (num_clusters != 0 && cluster_flags & CAIRO_TEXT_CLUSTER_FLAG_BACKWARD) {
+ for (i = 0; i < --j; i++) {
+ cairo_glyph_t tmp;
+
+ tmp = transformed_glyphs[i];
+ transformed_glyphs[i] = transformed_glyphs[j];
+ transformed_glyphs[j] = tmp;
+ }
}
return CAIRO_STATUS_SUCCESS;
More information about the cairo-commit
mailing list