显示文字这里我用了freetype库。
以左上角显示两行文字:
#include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <linux/fb.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <math.h> #include "show_font.h" #include <ft2build.h> #include FT_FREETYPE_H #include <freetype/ftglyph.h> unsigned char *hzkmem; unsigned char *fbmem; unsigned int line_width; unsigned int pixel_width; struct fb_var_screeninfo var; void lcd_put_pixel( int x, int y, unsigned int color ) { unsigned char *pen_8 = fbmem +y*line_width + x*pixel_width; unsigned short *pen_16; unsigned short *pen_32; unsigned char red,green,blue; pen_16 = (unsigned short *)pen_8; pen_32 = (unsigned short *)pen_8; switch( pixel_width*8 ) { case 8: *pen_8 = color; break; case 16: /* 565 */ red = (color>>16) & 0xff; green = (color>>8) & 0xff; blue = (color>>0) & 0xff; color = ((red>>3)<<11) | ((green>>2)<<5) |((blue>>3)); *pen_16 = color; break; case 32: *pen_32 = color; break; default: printf("can't support %ddpp ",pixel_width*8 ); break; } } void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y) { FT_Int i, j, p, q; FT_Int x_max = x + bitmap->width; FT_Int y_max = y + bitmap->rows; for ( i = x, p = 0; i < x_max; i++, p++ ) { for ( j = y, q = 0; j < y_max; j++, q++ ) { if ( i < 0 || j < 0 || i >= var.xres || j >= var.yres ) continue; //image[j][i] |= bitmap->buffer[q * bitmap->width + p]; lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]); } } } int main( int argc, char **argv ) { int hzk_fd; int fd_fb; struct fb_fix_screeninfo fix; int screen_size; FT_Library library; FT_Error error; FT_Face face; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ FT_BBox bbox; FT_Glyph glyph; int i; double angle; wchar_t *chinese_char = L"周zhou"; wchar_t *chinese_char2 = L"嵌入式Linux"; int line_box_ymin=800; int line_box_ymax=0; struct stat hzk_stat; fd_fb = open("/dev/fb0", O_RDWR ); if( fd_fb<0 ) { perror("oepn failed"); return -1; } if( ioctl( fd_fb, FBIOGET_VSCREENINFO, &var ) ) { printf("can't get var "); return -1; } if( ioctl( fd_fb, FBIOGET_FSCREENINFO, &fix ) ) { printf("can't get fix "); return -1; } line_width = var.xres * var.bits_per_pixel / 8; pixel_width = var.bits_per_pixel / 8; screen_size = var.xres * var.yres * var.bits_per_pixel / 8; fbmem = (unsigned char *)mmap( NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb,0 ); if( fbmem == (unsigned char *)-1 ) { printf("mmap is failed "); return -1; } memset( fbmem, 0, screen_size ); if( argc != 2 ) { printf("Usage: %s <font_file> ", argv[0]); return -1; } error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */ /* use 50pt at 100dpi */ error = FT_Set_Pixel_Sizes( face, 30, 0 ); /* set character size */ angle = ( 0.0 / 360 ) * 3.14159 * 2; /* use 25 degrees */ /* set up matrix */ matrix.xx = (FT_Fixed)( cos( angle ) * 0x10000L ); matrix.xy = (FT_Fixed)(-sin( angle ) * 0x10000L ); matrix.yx = (FT_Fixed)( sin( angle ) * 0x10000L ); matrix.yy = (FT_Fixed)( cos( angle ) * 0x10000L ); /* the pen position in 26.6 cartesian space coordinates; */ /* start at (0,24) relative to the upper left corner */ pen.x = (0) * 64; pen.y = ( var.yres - 24 ) * 64; for( i=0; i<wcslen(chinese_char); i++ ) { /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, chinese_char[i], FT_LOAD_RENDER ); if(error) { printf("FT_load_char error "); return -1; } error = FT_Get_Glyph(face->glyph, &glyph ); if(error) { printf("FT_Get_Glyph error "); return -1; } FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox); if( line_box_ymin > bbox.yMin ) line_box_ymin = bbox.yMin; if( line_box_ymax < bbox.yMax ) line_box_ymax = bbox.yMax; draw_bitmap( &face->glyph->bitmap, face->glyph->bitmap_left, var.yres - face->glyph->bitmap_top ); /* increment pen position */ pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } /* the pen position in 26.6 cartesian space coordinates; */ /* start at (0,24) relative to the upper left corner */ pen.x = (0) * 64; pen.y = ( var.yres-( line_box_ymax-line_box_ymin+24) ) * 64; for( i=0; i<wcslen(chinese_char2); i++ ) { /* set transformation */ FT_Set_Transform( face, &matrix, &pen ); /* load glyph image into the slot (erase previous one) */ error = FT_Load_Char( face, chinese_char2[i], FT_LOAD_RENDER ); if(error) { printf("FT_load_char error "); return -1; } error = FT_Get_Glyph(face->glyph, &glyph ); if(error) { printf("FT_Get_Glyph error "); return -1; } FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox); if( line_box_ymin > bbox.yMin ) line_box_ymin = bbox.yMin; if( line_box_ymax < bbox.yMax ) line_box_ymax = bbox.yMax; draw_bitmap( &face->glyph->bitmap, face->glyph->bitmap_left, var.yres - face->glyph->bitmap_top ); /* increment pen position */ pen.x += face->glyph->advance.x; pen.y += face->glyph->advance.y; } return 0; }
在屏幕的中间左右上下对称显示:
#include <sys/types.h> #include <sys/stat.h> #include <sys/mman.h> #include <linux/fb.h> #include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <math.h> #include "show_font.h" #include <ft2build.h> #include FT_FREETYPE_H #include <freetype/ftglyph.h> typedef struct TGlyph_ { FT_UInt index; /* glyph index */ FT_Vector pos; /* glyph origin on the baseline */ FT_Glyph image; /* glyph image */ } TGlyph, *PGlyph; #define MAX_GLYPHS 100 unsigned char *hzkmem; unsigned char *fbmem; unsigned int line_width; unsigned int pixel_width; struct fb_var_screeninfo var; void lcd_put_pixel( int x, int y, unsigned int color ) { unsigned char *pen_8 = fbmem +y*line_width + x*pixel_width; unsigned short *pen_16; unsigned short *pen_32; unsigned char red,green,blue; pen_16 = (unsigned short *)pen_8; pen_32 = (unsigned short *)pen_8; switch( pixel_width*8 ) { case 8: *pen_8 = color; break; case 16: /* 565 */ red = (color>>16) & 0xff; green = (color>>8) & 0xff; blue = (color>>0) & 0xff; color = ((red>>3)<<11) | ((green>>2)<<5) |((blue>>3)); *pen_16 = color; break; case 32: *pen_32 = color; break; default: printf("can't support %ddpp ",pixel_width*8 ); break; } } void draw_bitmap( FT_Bitmap* bitmap, FT_Int x, FT_Int y) { FT_Int i, j, p, q; FT_Int x_max = x + bitmap->width; FT_Int y_max = y + bitmap->rows; for ( i = x, p = 0; i < x_max; i++, p++ ) { for ( j = y, q = 0; j < y_max; j++, q++ ) { if ( i < 0 || j < 0 || i >= var.xres || j >= var.yres ) continue; //image[j][i] |= bitmap->buffer[q * bitmap->width + p]; lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]); } } } int Get_Glyphs_From_Wstr( FT_Face face, wchar_t* wstr, TGlyph glyphs[] ) { int n; PGlyph glyph = glyphs; int pen_x=0; int pen_y=0; int error; for( n=0; n<wcslen( wstr ); n++ ) { glyph->index = FT_Get_Char_Index( face, wstr[n] ); /* store current pen position */ glyph->pos.x = pen_x; glyph->pos.y = pen_y; error = FT_Load_Glyph( face, glyph->index, FT_LOAD_DEFAULT ); if ( error ) continue; error = FT_Get_Glyph( face->glyph, &glyph->image ); if ( error ) continue; /* translate the glyph image now */ FT_Glyph_Transform( glyph->image, 0, &glyph->pos ); pen_x += face->glyph->advance.x ; /* increment number of glyphs */ glyph++; } /* count number of glyphs loaded */ return (glyph - glyphs); } void compute_string_bbox( TGlyph glyphs[],FT_UInt num_glyphs,FT_BBox *abbox ) { FT_BBox bbox; int n; bbox.xMin = bbox.yMin = 32000; bbox.xMax = bbox.yMax = -32000; for ( n = 0; n < num_glyphs; n++ ) { FT_BBox glyph_bbox; FT_Glyph_Get_CBox( glyphs[n].image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox ); if (glyph_bbox.xMin < bbox.xMin) bbox.xMin = glyph_bbox.xMin; if (glyph_bbox.yMin < bbox.yMin) bbox.yMin = glyph_bbox.yMin; if (glyph_bbox.xMax > bbox.xMax) bbox.xMax = glyph_bbox.xMax; if (glyph_bbox.yMax > bbox.yMax) bbox.yMax = glyph_bbox.yMax; } *abbox = bbox; } void Draw_Glyphs( TGlyph glyphs[],FT_UInt num_glyphs,FT_Vector pen ) { int n; int error; for( n=0; n<num_glyphs; n++ ) { FT_Glyph_Transform( glyphs[n].image, 0, &pen ); /* convert glyph image to bitmap (destroy the glyph copy!) */ error = FT_Glyph_To_Bitmap( &glyphs[n].image, FT_RENDER_MODE_NORMAL, 0, /* no additional translation */ 1 ); /* destroy copy in "image" */ if ( !error ) { FT_BitmapGlyph bit = (FT_BitmapGlyph)glyphs[n].image; draw_bitmap( &bit->bitmap, bit->left, var.yres - bit->top ); FT_Done_Glyph( glyphs[n].image ); } } } int main( int argc, char **argv ) { int hzk_fd; int fd_fb; struct fb_fix_screeninfo fix; int screen_size; FT_Library library; FT_Error error; FT_Face face; FT_Matrix matrix; /* transformation matrix */ FT_Vector pen; /* untransformed origin */ FT_BBox bbox; TGlyph glyphs[MAX_GLYPHS]; /* glyphs table */ PGlyph glyph; /* current glyph in table */ FT_UInt num_glyphs; int i; double angle; wchar_t *chinese_char = L"周zhou"; wchar_t *chinese_char2 = L"嵌入式Linux"; int line_box_ymin=800; int line_box_ymax=0; int line_box_width; int line_box_hight; struct stat hzk_stat; fd_fb = open("/dev/fb0", O_RDWR ); if( fd_fb<0 ) { perror("oepn failed"); return -1; } if( ioctl( fd_fb, FBIOGET_VSCREENINFO, &var ) ) { printf("can't get var "); return -1; } if( ioctl( fd_fb, FBIOGET_FSCREENINFO, &fix ) ) { printf("can't get fix "); return -1; } line_width = var.xres * var.bits_per_pixel / 8; pixel_width = var.bits_per_pixel / 8; screen_size = var.xres * var.yres * var.bits_per_pixel / 8; fbmem = (unsigned char *)mmap( NULL, screen_size, PROT_READ | PROT_WRITE, MAP_SHARED,fd_fb,0 ); if( fbmem == (unsigned char *)-1 ) { printf("mmap is failed "); return -1; } memset( fbmem, 0, screen_size ); if( argc != 2 ) { printf("Usage: %s <font_file> ", argv[0]); return -1; } error = FT_Init_FreeType( &library ); /* initialize library */ /* error handling omitted */ error = FT_New_Face( library, argv[1], 0, &face ); /* create face object */ /* use 50pt at 100dpi */ error = FT_Set_Pixel_Sizes( face, 24, 0 ); /* set character size */ num_glyphs = Get_Glyphs_From_Wstr( face, chinese_char, glyphs); compute_string_bbox( glyphs, num_glyphs, &bbox ); line_box_width = bbox.xMax - bbox.xMin; line_box_hight = bbox.yMax - bbox.yMin; pen.x = (var.xres - line_box_width)/2*64; pen.y = (var.yres - line_box_hight)/2*64; Draw_Glyphs( glyphs, num_glyphs, pen ); num_glyphs = Get_Glyphs_From_Wstr( face, chinese_char2, glyphs); compute_string_bbox( glyphs, num_glyphs, &bbox ); line_box_width = bbox.xMax - bbox.xMin; line_box_hight = bbox.yMax - bbox.yMin; pen.x = (var.xres - line_box_width)/2*64; pen.y = pen.y-24*64; Draw_Glyphs( glyphs, num_glyphs, pen ); return 0; }
sd