Re: Trying to draw text on a pixbuf



Thanks for your answer. It is much uneasy than I thought.

I wrote that, thinking I was following your advices, but I got such weird results that I think I missed something :

void gdk_pixbuf_draw_text( GdkPixbuf *pixbuf, GtkWidget *widget, gchar *text, int x, int y) {
 GdkPixmap *temp_pixmap ;
 GdkPixbuf *temp_pixbuf ;
 PangoLayout *layout ;
 GdkGC *gc ;
 GdkColormap *cmap ;
 int sx, sy ;
 int i, j, rowstride ;
 guchar *pixels, *p ;

 /* render layout to temp_pixmap */
 layout = gtk_widget_create_pango_layout(widget, text) ;
 pango_layout_get_pixel_size(layout, &sx, &sy) ;
 temp_pixmap = gdk_pixmap_new(NULL, sx, sy, 24) ;
 gc = gdk_gc_new(temp_pixmap) ;

 gdk_gc_set_foreground(gc, base->white) ;
 gdk_gc_set_background(gc, base->black) ;
 gdk_draw_layout( temp_pixmap, gc, 0, 0, layout) ;

 /* render temp_pixmap to temp_pixbuf */
 cmap = gdk_colormap_get_system() ;
temp_pixbuf = gdk_pixbuf_get_from_drawable(NULL, temp_pixmap, cmap, 0, 0, 0, 0, sx, sy) ;

 /* add alpha and modify it */
gdk_pixbuf_add_alpha(temp_pixbuf, FALSE, 0, 0, 0) ; rowstride = gdk_pixbuf_get_rowstride(temp_pixbuf) ;
 pixels = gdk_pixbuf_get_pixels(temp_pixbuf) ;
 p = pixels ;

 printf("begin loop (%i, %i)\n", sx, sy) ;
 for (j=0 ; j<sy ; j++) {
   for (i=0 ; i<sx ; i++) {
     p[3] = p[0] ; /* copy red component to alpha */
     printf("%.2x ", p[3]) ;
     p[0] = 128 ; /* just for example, color will be medium gray */
     p[1] = 128 ;
     p[2] = 128 ;
     p += 4 ;
   }
   printf("\n") ;
   pixels += rowstride ;
   p = pixels ;
 }
 printf("end loop\n") ;

 /* copy to main pixbuf */
 gdk_pixbuf_copy_area( temp_pixbuf, 0, 0, sx, sy, pixbuf, x, y) ;
} Here's what I get on my console when calling gdk_pixbuf_draw_text(pixbuf, drawing_area, "aze", 10, 20) ; :

begin loop (21, 16)
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff 00
80 80 80 80 80 00 ff ff ff ff 00 00 ff ff ff 00 00 ff 00 00 ff
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ff
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff
80 80 80 80 80 00 00 00 ff 00 00 00 ff ff ff 00 00 ff 00 00 ff
80 80 80 80 80 00 00 ff 00 00 00 00 00 00 00 00 00 ff 00 ff ff
80 80 80 80 80 00 00 ff 00 00 00 00 00 00 00 00 00 00 ff 00 ff
80 80 80 80 80 00 ff ff ff ff 00 00 ff ff ff 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
80 80 80 80 80 00 00 00 00 00 00 00 00 00 00 00 a9 70 00 00 00
end loop

My pixels pointer doesn't seem to point the beginning of my pixbuf, since the "ff" are more or less looking like "zea" and not "aze".
Also, I don't understand where these weird "80" comes from.
Curiouser, if I change "p[3] = p[0]" to "p[3]=p[1]" or "p[3]=p[2]", the results are quite different (but I can see the "zea"), whereas I'd have thought that all channels would be the same, since I use white as foreground color. Last, the "graphics" results are awful. I can hardly recognize the "aze" (but it's "aze", not "zea").

I'm quite upset. There are too much weird things for blaming GTK. It must be my fault, but I don't see...



Chris Seaton a écrit :

I was doing this a while ago.

Specifically, I was using Pango to create text for OpenGL textures, but I needed to have rendered text with an alpha channel to do that, just like you do.

Pango is pretty shit in that it won't (as far as I can tell) render an alpha channel. I mean how basic is that?

You can't just render onto a black background and then set black to be transparent, as remember that the text could be antialised.

What I did was to render white text on a black background into a pixbuf, add an alpha channel (there's a function for that) then itterate through each pixel in the pixbuf, copying the red channel into the alpha channel (remember we rendered white on black, so the text will be opaque and the background transparent), and then setting the red green and blue channels to be whatever colour I wanted.

You can then render that pixbuf.

There will be some very slight artifacts does to sub pixel antialisiaing, so I wouldn'e be writing GIMP's text tool using this. Anyone not knowledgeable about antialiasing will probably not notice it though.

Chris





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]