Trying to figure out how to render a single character represented by a FT_Bitmap in X
joe M
joe9mail at gmail.com
Sat Feb 16 19:34:33 PST 2013
> Thanks a lot for your very informative comments. They were very
> helpful. I am trying to get a working program based on your comments.
> I will email it to the list once I have a working version.
For the record, a sample program to write out the Char 'I' to X:
#include <X11/Xlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#define WIDTH 32
#define HEIGHT 40
/* origin is the upper left corner */
unsigned char image[HEIGHT][WIDTH];
unsigned char pixmap[(WIDTH/8)*HEIGHT];
/* Replace this function with something useful. */
void draw_bitmap( FT_Bitmap* bitmap, FT_Int pitch, FT_Int left, FT_Int top) {
int h, w, bitpos, bytepos, row, bitmapw;
char byte ;
int twidth = left + bitmap->width;
/* blank out above the top to the max height */
for (h = 0; h < (HEIGHT - top); h++) {
for (w = 0; w < twidth; w++) {
image[h][w] = 0;
}
}
for (h = (HEIGHT - top); h < HEIGHT; h++) {
row = pitch * (h - (HEIGHT - top));
for (w = 0; w < twidth; w++) {
if (w < left) {
image[h][w] = 0;
} else {
bitmapw = w-left;
bytepos = bitmapw / 8;
/* as bits are laid out from high bit to the low bit */
bitpos = 7 - (bitmapw % 8);
byte = (char) (bitmap->buffer[row+bytepos]);
/* If you want the k-th bit of n, then do */
/* (n & ( 1 << k )) >> k */
image[h][w] = (byte & ( 1 << bitpos )) >> bitpos;
/* if (12 == row) fprintf(stdout,
"w: %02x, bitmapw: %02x, byte: %02x, bitpos: %02x, image: %01x ",
w,bitmapw,byte,bitpos,image[w][h]); */
}
}
}
}
void show_image( int width ) {
int h, w;
for ( h = 0; h < HEIGHT; h++ ) {
fprintf(stdout,"row: %02d",h);
for ( w = 0; w < width; w++ )
putchar( image[h][w] == 0 ? ' ' : '.' );
putchar( '\n' );
}
}
void to_xpixmap( int width ) {
int h, w;
for ( h = 0; h < HEIGHT; h++ ) {
for ( w = 0; w < (width/8); w++ ) {
pixmap[(h*(width/8))+w] =
(image[h][((w*8)+7)]<<7) |
(image[h][((w*8)+6)]<<6) |
(image[h][((w*8)+5)]<<5) |
(image[h][((w*8)+4)]<<4) |
(image[h][((w*8)+3)]<<3) |
(image[h][((w*8)+2)]<<2) |
(image[h][((w*8)+1)]<<1) |
(image[h][((w*8)+0)]<<0) ;
/* fprintf(stdout,"w: %02d, h: %02d -- %02x\n", */
/* w,h,pixmap[(h*(width/8))+w]); */
}
}
}
int main( int argc, char** argv ) {
FT_Library library;
FT_Face face;
FT_GlyphSlot slot;
FT_Matrix matrix; /* transformation matrix */
FT_Vector pen; /* untransformed origin */
FT_Error error;
int pitch;
unsigned char *bitmap;
int h,wi;
int twidth = 0;
Display *d;
Window w;
XEvent e;
int s,i;
Pixmap p;
unsigned int bwidth, bheight;
int hotspot_x, hotspot_y;
/* int target_height; */
int n, num_chars;
char *msg = "Hello, World!";
error = FT_Init_FreeType( &library ); /* initialize library */
/* error handling omitted */
error = FT_New_Face(
library,
"/usr/share/fonts/liberation-fonts/LiberationMono-Regular.ttf",
0, &face );/* create face object */
/* error handling omitted */
FT_Set_Pixel_Sizes(face, 0, 48);
error = FT_Load_Char( face, 'I', FT_LOAD_RENDER | FT_LOAD_MONOCHROME );
if (0 != error) {
fprintf(stderr,"could not load FT_Load_Char\n");
fflush(stderr);
exit(1);
}
slot = face->glyph;
fprintf(stdout,"returned bitmap characterstics:\n \
bitmap_left: %d,\n\
bitmap_top: %d,\n\
rows: %d, \n\
width: %d, \n\
pitch: %d, \n\
num_grays: %d, \n\
pixel_mode: %d\n",
slot->bitmap_left,
slot->bitmap_top,
slot->bitmap.rows,
slot->bitmap.width,
slot->bitmap.pitch,
slot->bitmap.num_grays,
slot->bitmap.pixel_mode);
/* if ( pitch < 0 ) pitch = -pitch; */
/* bitmap = (unsigned char *) malloc(slot->bitmap.rows * pitch); */
/* memcpy(bitmap, slot->bitmap.buffer, pitch*slot->bitmap.rows ); */
/* fprintf(stdout,"pitch: %d, rows: %d, pitch * slot->bitmap.rows: %d\n", */
/* pitch, */
/* slot->bitmap.rows, */
/* pitch * slot->bitmap.rows); */
for(i = 0; i < slot->bitmap.pitch * slot->bitmap.rows; i++) {
if (0 == i % slot->bitmap.pitch) fprintf(stdout,"\n");
fprintf(stdout,"%d: 0x%02X ", i,slot->bitmap.buffer[i]);
fflush(stdout);
}
fprintf(stdout,"\n");
/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap.pitch,
slot->bitmap_left,
slot->bitmap_top );
twidth = (slot->bitmap_left+slot->bitmap.width);
show_image(twidth);
to_xpixmap(twidth);
fprintf(stdout,"\n");
fflush(stdout);
FT_Done_Face ( face );
FT_Done_FreeType( library );
d = XOpenDisplay(NULL);
if (d == NULL) {
fprintf(stderr, "Cannot open display\n");
exit(1);
}
s = DefaultScreen(d);
w = XCreateSimpleWindow(d, RootWindow(d, s), 10, 10, 100, 100, 1,
BlackPixel(d, s), WhitePixel(d, s));
XSelectInput(d, w, ExposureMask | KeyPressMask);
XMapWindow(d, w);
while (1) {
XNextEvent(d, &e);
if (e.type == Expose) {
XFillRectangle(d, w, DefaultGC(d, s), 20, 20, 10, 10);
XDrawString(d, w, DefaultGC(d, s), 10, 50, msg, strlen(msg));
XDrawPoint(d, w, DefaultGC(d,s), 30, 30);
XSync(d, False);
usleep(100000);
p = XCreateBitmapFromData(d, w, (unsigned char *) pixmap ,
twidth ,
(unsigned int) HEIGHT);
XWriteBitmapFile(d,"test.xbm",p,twidth,HEIGHT,0,0);
XCopyPlane(d, p , w, DefaultGC(d,s),
0, 0,
twidth, HEIGHT,
40, 40,1);
XSync(d, False);
usleep(100000);
}
if (e.type == KeyPress) break;
}
XCloseDisplay(d);
return 0;
}
More information about the xorg
mailing list