Re: render texts to a buffer/drawable



Hi Ronald,

Ronald Bultje wrote:
>                 color.red = (guint16)(options->colors[0]*65535.0);
>                 color.green = (guint16)(options->colors[1]*65535.0);
>                 color.blue = (guint16)(options->colors[2]*65535.0);

In my app, I use a 1 bit pixmap (bitmap), since every server supports
that (and there's less data to copy from the server to the client). Just
use 0x0 for the background, and 0x1 for the foreground.

>                 w = gdk_text_width(font, text, strlen(text));
>                 h = gdk_text_height(font, text, strlen(text));

I use text_extents, I think it's a little quicker.

>                 pixmap = gdk_pixmap_new(NULL, w, h, 24);

You can bitdepth 1 here I think.

>                 gc = gdk_gc_new(pixmap);
>                 gdk_gc_set_foreground(gc, &color);
>                 gdk_draw_string(pixmap, font, gc, 0, h, text);

I think you need to clear the background before you render the text ...
draw a filled rectangle in the background colour.

>                 image = gdk_image_get(pixmap, 0,0,w,h);
>                 data = malloc(sizeof(guchar)*w*h*4);
> 
>                 for (y=0;y<h;y++)
>                 {
>                         for (x=0;x<w;x++)
>                         {
>                                 pixel = gdk_image_get_pixel(image,x,y);
>                                 data[(y*w+x)*4] = pixel/(256^3);
>                                 data[(y*w+x)*4+1] = (pixel/(256^2))%256;
>                                 data[(y*w+x)*4+2] = (pixel/256)%(256^2);
>                                 data[(y*w+x)*4+3] = 255;
>                         }
>                 }

I think this will be slow and unreliable :-( For 1 bit XImages, you can
unpack yourself pretty easily (this is Xlib, you'll need to change the
names for gdk):

-- 
static void
unpack_image( XImage *xim, unsigned char *msk )
{
        int x, y, b, i;
        unsigned char *p, q;

        for( i = 0, y = 0; y < xim->height; y++ ) {
                p = (unsigned char *) xim->data + y *
xim->bytes_per_line;
                q = *p++;

                for( b = 0, x = 0; x < xim->width; x++, b++, i++ ) {
                        if( b == 8 ) {
                                b = 0;
                                q = *p++;
                        }

                        if( xim->bitmap_bit_order == LSBFirst ) {
                                if( q & 0x1 )
                                        msk[i] = 255;
                                else
                                        msk[i] = 0;
                                q = q >> 1;
                        }
                        else {
                                if( q & 0x80 )
                                        msk[i] = 255;
                                else
                                        msk[i] = 0;
                                q = q << 1;
                        }
                }
        }
}
-- 

I'm sure there are things to handle these conversions for you in the
newer pixbuf libraries ... I hacked this a while ago.

Something else you might consider is anti-aliasing ... gimp 1.1 asks for
a font twice the size required, then does a 2x2 block average. Not the
best way to anti-alias, but very easy, and it does look better. I guess
you should consider using XRender really (is this wrapped by gdk yet?
not sure).

Good luck,

John




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