[cairo-commit] 3 commits - src/cairo-polygon.c src/cairo-xlib-surface.c src/cairo-xlib-surface-private.h test/any2ppm.c test/pdf2png.c
Chris Wilson
ickle at kemper.freedesktop.org
Fri Jun 11 04:09:12 PDT 2010
src/cairo-polygon.c | 30 +++++++++++++++---------------
src/cairo-xlib-surface-private.h | 1 +
src/cairo-xlib-surface.c | 31 +++++++++++++++++++++++++++++++
test/any2ppm.c | 9 ++++-----
test/pdf2png.c | 10 +++++-----
5 files changed, 56 insertions(+), 25 deletions(-)
New commits:
commit 506b2ebe714d61a64972b607a42a55e48d1c722a
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 11 12:04:39 2010 +0100
test/pdf2png: Don't use DEST_OVER as poppler starts using subpixel text.
Using DEST_OVER in this form to paint the background white fails in the
presence of subpixel geometry (particular text), so remove the hack and
simply paint the background white prior to passing the surface to
poppler. KISS.
diff --git a/test/any2ppm.c b/test/any2ppm.c
index 55b4c7e..d6bc779 100644
--- a/test/any2ppm.c
+++ b/test/any2ppm.c
@@ -357,16 +357,15 @@ _poppler_render_page (const char *filename,
poppler_page_get_size (page, &width, &height);
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
cr = cairo_create (surface);
- poppler_page_render (page, cr);
- g_object_unref (page);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
cairo_set_source_rgb (cr, 1., 1., 1.);
cairo_paint (cr);
+ poppler_page_render (page, cr);
+ g_object_unref (page);
+
status = cairo_status (cr);
cairo_destroy (cr);
diff --git a/test/pdf2png.c b/test/pdf2png.c
index f60170c..279ccfe 100644
--- a/test/pdf2png.c
+++ b/test/pdf2png.c
@@ -74,17 +74,17 @@ int main (int argc, char *argv[])
poppler_page_get_size (page, &width, &height);
- surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+ surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, width, height);
cr = cairo_create (surface);
cairo_surface_destroy (surface);
- poppler_page_render (page, cr);
- g_object_unref (page);
-
- cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER);
+ /* fill the background with white */
cairo_set_source_rgb (cr, 1., 1., 1.);
cairo_paint (cr);
+ poppler_page_render (page, cr);
+ g_object_unref (page);
+
status = cairo_surface_write_to_png (cairo_get_target (cr),
output_filename);
cairo_destroy (cr);
commit edb73b6dcf1adce40d6c10c492e3f78556e22b85
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 11 11:16:42 2010 +0100
xlib: Adjust trapezoid precision based on antialias.
Render supports two modes of precision when rendering trapezoids.
Precise specifies points sampling on a 15x17 grid, ala pixman. Imprecise
allows the driver more freedom in the methods used, which may be more
amenable to acceleration. Choose to use the imprecise mode by default,
but still allow users to force the more rigidly specified precision by
changing the antialias mode.
diff --git a/src/cairo-xlib-surface-private.h b/src/cairo-xlib-surface-private.h
index 8004c8d..34732b4 100644
--- a/src/cairo-xlib-surface-private.h
+++ b/src/cairo-xlib-surface-private.h
@@ -94,6 +94,7 @@ struct _cairo_xlib_surface {
cairo_filter_t filter;
cairo_extend_t extend;
cairo_bool_t has_component_alpha;
+ int precision;
XTransform xtransform;
uint32_t a_mask;
diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 7593316..b5ef703 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -1056,6 +1056,35 @@ _cairo_xlib_surface_set_picture_clip_rects (cairo_xlib_display_t *display,
}
static void
+_cairo_xlib_surface_set_precision (cairo_xlib_display_t *display,
+ cairo_xlib_surface_t *surface,
+ cairo_antialias_t antialias)
+{
+ int precision;
+
+ switch (antialias) {
+ case CAIRO_ANTIALIAS_NONE:
+ case CAIRO_ANTIALIAS_DEFAULT:
+ precision = PolyModePrecise;
+ break;
+ case CAIRO_ANTIALIAS_SUBPIXEL:
+ case CAIRO_ANTIALIAS_GRAY:
+ precision = PolyModeImprecise;
+ break;
+ }
+
+ if (surface->precision != precision) {
+ XRenderPictureAttributes pa;
+
+ pa.poly_mode = precision;
+ XRenderChangePicture (display->display, surface->dst_picture,
+ CPPolyMode, &pa);
+
+ surface->precision = precision;
+ }
+}
+
+static void
_cairo_xlib_surface_ensure_dst_picture (cairo_xlib_display_t *display,
cairo_xlib_surface_t *surface)
{
@@ -2730,6 +2759,7 @@ _cairo_xlib_surface_composite_trapezoids (cairo_operator_t op,
goto BAIL;
_cairo_xlib_surface_ensure_dst_picture (display, dst);
+ _cairo_xlib_surface_set_precision (display, dst, antialias);
status = _cairo_xlib_surface_set_attributes (display,
src, &attributes,
@@ -3082,6 +3112,7 @@ found:
surface->filter = CAIRO_FILTER_NEAREST;
surface->extend = CAIRO_EXTEND_NONE;
surface->has_component_alpha = FALSE;
+ surface->precision = PolyModePrecise;
surface->xtransform = identity;
surface->clip_region = NULL;
commit 290749bdb5c634c030db81722214661c34344403
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date: Fri Jun 11 10:59:17 2010 +0100
polygon: Reorder conditionals based on likelihood.
The vast majority of edges will be unclipped, so process those first.
diff --git a/src/cairo-polygon.c b/src/cairo-polygon.c
index 49ba7a3..64fef47 100644
--- a/src/cairo-polygon.c
+++ b/src/cairo-polygon.c
@@ -140,7 +140,7 @@ _add_edge (cairo_polygon_t *polygon,
assert (top < bottom);
- if (polygon->num_edges == polygon->edges_size) {
+ if (unlikely (polygon->num_edges == polygon->edges_size)) {
if (! _cairo_polygon_grow (polygon))
return;
}
@@ -197,7 +197,20 @@ _add_clipped_edge (cairo_polygon_t *polygon,
if (bottom <= limits->p1.y)
continue;
- if (p1->x <= limits->p1.x && p2->x <= limits->p1.x)
+ if (p1->x >= limits->p1.x && p2->x >= limits->p1.x &&
+ p1->x <= limits->p2.x && p2->x <= limits->p2.x)
+ {
+ top_y = top;
+ if (top_y < limits->p1.y)
+ top_y = limits->p1.y;
+
+ bot_y = bottom;
+ if (bot_y > limits->p2.y)
+ bot_y = limits->p2.y;
+
+ _add_edge (polygon, p1, p2, top_y, bot_y, dir);
+ }
+ else if (p1->x <= limits->p1.x && p2->x <= limits->p1.x)
{
p[0].x = limits->p1.x;
p[0].y = limits->p1.y;
@@ -229,19 +242,6 @@ _add_clipped_edge (cairo_polygon_t *polygon,
_add_edge (polygon, &p[0], &p[1], top_y, bot_y, dir);
}
- else if (p1->x >= limits->p1.x && p2->x >= limits->p1.x &&
- p1->x <= limits->p2.x && p2->x <= limits->p2.x)
- {
- top_y = top;
- if (top_y < limits->p1.y)
- top_y = limits->p1.y;
-
- bot_y = bottom;
- if (bot_y > limits->p2.y)
- bot_y = limits->p2.y;
-
- _add_edge (polygon, p1, p2, top_y, bot_y, dir);
- }
else
{
int left_y, right_y;
More information about the cairo-commit
mailing list