[cairo-commit] 3 commits - src/cairo-user-font.c src/cairo-xlib-surface.c util/font-view.c util/Makefile.am

Chris Wilson ickle at kemper.freedesktop.org
Tue Jun 2 10:17:20 PDT 2009


 src/cairo-user-font.c    |    1 
 src/cairo-xlib-surface.c |   30 ++-----
 util/Makefile.am         |    5 +
 util/font-view.c         |  184 +++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 201 insertions(+), 19 deletions(-)

New commits:
commit 21550a753059b4f880f03ea96148befaa34a6426
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 2 18:08:45 2009 +0100

    [user-font] Set the initial colour to white
    
    An issue occured when using subpixel antialiasing with user-fonts and
    XRender - the glyphs were transparent, as demonstrated by the font-view
    example.
    
    The problem lies in that enabling subpixel antialiasing triggers use of an
    ARGB32 image surface for rendering the glyph, but the default colour is
    black (so the only information is in the alpha-channel). Given an ARGB32
    glyph XRender treats it as a per-channel mask, but since the R,G,B
    channels were uniformly zero, the glyph is rendered as transparent.
    
    Fix this by setting the initial colour to white before rendering the image
    surface for a user-font glyph, which generates the appropiate gray-level
    mask by default.

diff --git a/src/cairo-user-font.c b/src/cairo-user-font.c
index 6b4f0d4..5ab9751 100644
--- a/src/cairo-user-font.c
+++ b/src/cairo-user-font.c
@@ -92,6 +92,7 @@ _cairo_user_scaled_font_create_meta_context (cairo_user_scaled_font_t *scaled_fo
     cairo_set_matrix (cr, &scaled_font->base.scale);
     cairo_set_font_size (cr, 1.0);
     cairo_set_font_options (cr, &scaled_font->base.options);
+    cairo_set_source_rgb (cr, 1., 1., 1.);
 
     return cr;
 }
commit b5799e073e4e404aea277b7640eeee2120318823
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Tue Jun 2 18:07:31 2009 +0100

    [xlib] Use bswap_32
    
    Byteswap the ARGB32 glyphs using bswap_32 instead of open-coding.

diff --git a/src/cairo-xlib-surface.c b/src/cairo-xlib-surface.c
index 25bdfb3..aa6b3d1 100644
--- a/src/cairo-xlib-surface.c
+++ b/src/cairo-xlib-surface.c
@@ -3619,14 +3619,13 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
 	    }
 	    n = new;
 	    d = data;
-	    while (c--)
-	    {
+	    do {
 		char	b = *d++;
 		b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
 		b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
 		b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
 		*n++ = b;
-	    }
+	    } while (--c);
 	    data = new;
 	}
 	break;
@@ -3634,28 +3633,21 @@ _cairo_xlib_surface_add_glyph (Display *dpy,
 	break;
     case CAIRO_FORMAT_ARGB32:
 	if (_native_byte_order_lsb() != (ImageByteOrder (dpy) == LSBFirst)) {
-	    unsigned int    c = glyph_surface->stride * glyph_surface->height;
-	    unsigned char   *d;
-	    unsigned char   *new, *n;
+	    unsigned int c = glyph_surface->stride * glyph_surface->height / 4;
+	    const uint32_t *d;
+	    uint32_t *new, *n;
 
-	    new = malloc (c);
+	    new = malloc (4 * c);
 	    if (unlikely (new == NULL)) {
 		status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
 		goto BAIL;
 	    }
 	    n = new;
-	    d = data;
-	    while (c >= 4)
-	    {
-		n[3] = d[0];
-		n[2] = d[1];
-		n[1] = d[2];
-		n[0] = d[3];
-		d += 4;
-		n += 4;
-		c -= 4;
-	    }
-	    data = new;
+	    d = (uint32_t *) data;
+	    do {
+		*n++ = bswap_32 (*d++);
+	    } while (--c);
+	    data = (uint8_t *) new;
 	}
 	break;
     case CAIRO_FORMAT_RGB24:
commit 56e9765f82a64940b36a64688267fbe5d1c8919e
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Fri Jan 2 14:25:04 2009 +0000

    [util] Add font-view
    
    A C variant of Behdad's python example font viewer.

diff --git a/util/Makefile.am b/util/Makefile.am
index 56b941c..103bc71 100644
--- a/util/Makefile.am
+++ b/util/Makefile.am
@@ -24,6 +24,11 @@ backtrace_symbols_la_LIBADD  = -lbfd -liberty
 
 #malloc_stats_la_LIBADD  = $(backtrace_symbols_la_LIBADD) backtrace-symbols.lo
 
+noinst_PROGRAMS = font-view
+
+font_view_CFLAGS = $(gtk_CFLAGS)
+font_view_LDADD = ../src/libcairo.la $(gtk_LIBS)
+
 EXTRA_DIST += \
 	COPYING \
 	xr2cairo \
diff --git a/util/font-view.c b/util/font-view.c
new file mode 100644
index 0000000..07d9e2e
--- /dev/null
+++ b/util/font-view.c
@@ -0,0 +1,184 @@
+/*
+ * Copyright © 2008 Behdad Esfahbod
+ * Copyright © 2009 Chris Wilson
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without
+ * fee, provided that the above copyright notice appear in all copies
+ * and that both that copyright notice and this permission notice
+ * appear in supporting documentation, and that the name of
+ * Chris Wilson not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Chris Wilson makes no representations about the
+ * suitability of this software for any purpose.  It is provided "as
+ * is" without express or implied warranty.
+ *
+ * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
+ * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
+ * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * Author: Chris Wilson <chris at chris-wilson.co.uk>
+ */
+
+#include <gtk/gtk.h>
+#include <cairo.h>
+
+struct options {
+    const char *text;
+    const char *family;
+    cairo_font_weight_t weight;
+    cairo_font_slant_t slant;
+    double size;
+    int PAD;
+    const char *png;
+};
+
+static void
+draw (cairo_t *cr, struct options *options)
+{
+    cairo_text_extents_t extents;
+    cairo_font_extents_t font_extents;
+
+    cairo_select_font_face (cr,
+			    options->family, options->slant, options->weight);
+    cairo_set_font_size (cr, options->size);
+
+    cairo_text_extents (cr, options->text, &extents);
+    cairo_translate (cr,
+		     options->PAD - extents.x_bearing,
+		     options->PAD - extents.y_bearing);
+
+    cairo_font_extents (cr, &font_extents);
+    cairo_rectangle (cr, 0, -font_extents.ascent,
+		      extents.x_advance, font_extents.height);
+    cairo_move_to (cr, -options->PAD, 0);
+    cairo_line_to (cr, extents.width + options->PAD, 0);
+    cairo_set_source_rgba (cr, 1, 0, 0, .7);
+    cairo_stroke (cr);
+
+    cairo_rectangle (cr,
+		     extents.x_bearing, extents.y_bearing,
+		     extents.width, extents.height);
+    cairo_set_source_rgba (cr, 0, 1, 0, .7);
+    cairo_stroke (cr);
+
+    cairo_move_to (cr, 0, 0);
+    cairo_set_source_rgb (cr, 0, 0, 1);
+    cairo_show_text (cr, options->text);
+    cairo_fill (cr);
+}
+
+static gboolean
+expose_event (GtkWidget *w, GdkEventExpose *ev, struct options *options)
+{
+    cairo_t *cr;
+
+    cr = gdk_cairo_create (w->window);
+
+    cairo_set_source_rgb (cr, 1, 1, 1);
+    cairo_paint (cr);
+
+    draw (cr, options);
+
+    cairo_destroy (cr);
+
+    if (options->png) {
+	cairo_surface_t *image;
+
+	image = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
+		                            w->allocation.width,
+					    w->allocation.height);
+	cr = cairo_create (image);
+	cairo_set_source_rgb (cr, 1, 1, 1);
+	cairo_paint (cr);
+
+	draw (cr, options);
+
+	cairo_destroy (cr);
+	cairo_surface_write_to_png (image, options->png);
+	cairo_surface_destroy (image);
+    }
+
+    return TRUE;
+}
+
+static void
+size_request (GtkWidget *w, GtkRequisition *req , struct options *options)
+{
+    cairo_surface_t *dummy;
+    cairo_t *cr;
+    cairo_text_extents_t extents;
+
+    dummy = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 0, 0);
+    cr = cairo_create (dummy);
+    cairo_surface_destroy (dummy);
+
+    cairo_select_font_face (cr,
+			    options->family, options->slant, options->weight);
+    cairo_set_font_size (cr, options->size);
+
+    cairo_text_extents (cr, options->text, &extents);
+    cairo_destroy (cr);
+
+    req->width = extents.width + 2 * options->PAD;
+    req->height = extents.height + 2 * options->PAD;
+}
+
+int
+main (int argc, char **argv)
+{
+    GtkWidget *window;
+    struct options options = {
+	"The Quick Brown Fox Jumps Over The Lazy Dog!",
+	"@cairo:small-caps",
+	CAIRO_FONT_WEIGHT_NORMAL,
+	CAIRO_FONT_SLANT_NORMAL,
+	48,
+	30,
+	"font-view.png"
+    };
+
+    gtk_init (&argc, &argv);
+
+    /* rudimentary argument processing */
+    if (argc >= 2) {
+	options.family = argv[1];
+    }
+    if (argc >= 3) {
+	if (strcmp (argv[2], "italic") == 0)
+	    options.slant = CAIRO_FONT_SLANT_ITALIC;
+	else if (strcmp (argv[2], "oblique") == 0)
+	    options.slant = CAIRO_FONT_SLANT_OBLIQUE;
+	else
+	    options.slant = atoi (argv[2]);
+    }
+    if (argc >= 4) {
+	if (strcmp (argv[3], "bold") == 0)
+	    options.weight = CAIRO_FONT_WEIGHT_BOLD;
+	else
+	    options.weight = atoi (argv[3]);
+    }
+    if (argc >= 5) {
+	options.size = atof (argv[4]);
+    }
+    if (argc >= 6) {
+	options.text = argv[5];
+    }
+
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    g_signal_connect (window, "size-request",
+		      G_CALLBACK (size_request), &options);
+    g_signal_connect (window, "expose-event",
+		      G_CALLBACK (expose_event), &options);
+    g_signal_connect (window, "delete-event",
+		      G_CALLBACK (gtk_main_quit), NULL);
+
+    gtk_window_present (GTK_WINDOW (window));
+    gtk_main ();
+
+    return 0;
+}


More information about the cairo-commit mailing list