tags:

views:

153

answers:

2

I'm trying to get a bitmap rendered by Pango with a given character, in this case the letter "T". I thought this should work, but it just prints out garbage..

In this code, gtk_window is already initialized as a GTK window.

int width, height;
PangoLayout *layout = gtk_widget_create_pango_layout(gtk_window, "T");
PangoFontDescription *fontdesc = pango_font_description_from_string("Terminus 12");
pango_layout_set_font_description (layout, fontdesc);
pango_layout_get_pixel_size (layout, &width, &height);

GdkPixmap *temp_pixmap = gdk_pixmap_new(NULL, width, height, 24) ;
GdkGC *gc = gdk_gc_new(temp_pixmap);
gdk_draw_layout( temp_pixmap, gc, 0, 0, layout) ;

GdkColormap *cmap = gdk_colormap_get_system() ;
GdkPixbuf *temp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, temp_pixmap,
                                       cmap, 0, 0, 0, 0, width, height);

int n_channels = gdk_pixbuf_get_n_channels (temp_pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(temp_pixbuf);
guchar *pixels = gdk_pixbuf_get_pixels(temp_pixbuf);

int i,j;
for (j=0; j<height; j++) {
    for (i=0; i<(width*n_channels); i++) {
        printf("%02x ",
               *(pixels + i + j*rowstride));
    }
    printf("\n");
}

The output is different every time, but an example:

dd 24 f8 dd 24 f8 8f 28 28 8f 28 28 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
ef 14 ce 00 00 00 d0 00 20 00 00 00 ef 02 02 d0 00 01 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 fc 00 00 00 00 00 ef 02 02 00 03 40 00 00 b9 00 00 c8 
00 00 01 00 00 07 00 00 07 00 00 00 00 00 02 00 00 00 00 00 d0 00 00 c8 
00 00 01 00 00 00 00 00 03 00 00 00 00 00 00 00 00 00 00 00 04 00 00 00 
00 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 12 ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 7a 4e 00 00 00 01 00 00 00 00 00 00 00 00 00 01 ff ff ff ff ff ff 
ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Which looks nothing like the letter "T"!

Any idea what I'm doing wrong? Thanks!

A: 

Just a few basic hints, haven't tried your code:

  • You don't mention error-checking; you should go through and see that all the various GTK+/GDK calls succeeed. They should all do NULL-checking on inputs and emit warnings, but still.
  • You're printing all channels at the same time, which might lead to a hard-to-interpret image visually. I tried filtering out two of the channels in your data, but that didn't help. Of course, since you say the output is different every time, that was a long-shot.
  • I'm not sure about the synchronicity of the GDK drawing calls, if they are guaranteed to happen immediately and then return, or if they can be deferred to some later "update dirty areas" handler.
unwind
+2  A: 

Okay, I figured it out. I needed to set the colors correctly, and clear the area before drawing using gdk_draw_rectangle:

PangoLayout *layout = gtk_widget_create_pango_layout(me->gtk_window, "T");
int width, height;
PangoFontDescription *fontdesc = pango_font_description_from_string("Sans 10");
pango_layout_set_font_description (layout, fontdesc);
pango_layout_get_pixel_size (layout, &width, &height);

GdkPixmap *temp_pixmap = gdk_pixmap_new(NULL, width, height, 24);
GdkGC *gc = gdk_gc_new(temp_pixmap);

GdkColor white = {0,0xFF00,0xFF00,0xFF00};
GdkColor black = {0,0,0,0};

GdkColormap *cmap = gdk_gc_get_colormap(gc);

gdk_gc_set_rgb_fg_color(gc, &black);
gdk_gc_set_rgb_bg_color(gc, &white);
gdk_draw_rectangle(temp_pixmap, gc, TRUE, 0, 0, width, height);

gdk_gc_set_rgb_fg_color(gc, &white);
gdk_gc_set_rgb_bg_color(gc, &black);
gdk_draw_layout(temp_pixmap, gc, 0, 0, layout);

GdkPixbuf *temp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, temp_pixmap,
                                        cmap, 0, 0, 0, 0, width, height);

int n_channels = gdk_pixbuf_get_n_channels (temp_pixbuf);
int rowstride = gdk_pixbuf_get_rowstride(temp_pixbuf);
guchar *pixels = gdk_pixbuf_get_pixels(temp_pixbuf);

int i,j;
for (j=0; j<height; j++) {
    for (i=0; i<(width*n_channels); i++) {
        printf("%02x ",
               *(pixels + i + j*rowstride));
    }
    printf("\n");
}

gives me:

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
c5 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff e3 
25 30 33 33 33 33 33 33 3d 68 ba f6 ff d8 86 4a 35 33 33 33 33 33 31 2a 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 0c 41 a7 f1 fe cc 66 1c 03 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Steve