[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