#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <linux/fb.h>
#include <math.h>
#include <wchar.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include FT_GLYPH_H
unsigned char *fb_mem = NULL;
unsigned char *fb_hzk = NULL;
int sreen_size = 0;
struct fb_var_screeninfo fb_var;
struct fb_fix_screeninfo fb_fix;
int fd_fb = 0;
int fd_HZK = 0;
unsigned int line_width;
unsigned int pixel_width;
FT_Vector pen;
FT_Face face;
typedef struct TGlyph_ {
FT_UInt index;
FT_Vector pos;
FT_Glyph image;
} TGlyph, *PGlyph;
void lcd_draw_point(int x, int y, int color) //0x00RRGGBB
{
unsigned char *pen_8 = fb_mem + y*line_width + x*pixel_width;
unsigned short *pen_16;
unsigned int *pen_32;
unsigned int red;
unsigned int green;
unsigned int blue;
pen_16 = (unsigned short *)pen_8;
pen_32 = (unsigned int *)pen_8;
switch(fb_var.bits_per_pixel){
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 %dbpp\n", fb_var.bits_per_pixel);
break;
}
}
}
// void lcd_draw_ascii(int x, int y, unsigned char c) //8*16
// {
// unsigned char *dot = (unsigned char *)&fontdata_8x16[c*16];
// unsigned char byte;
// int i,b;
// for(i=0; i<16; i++) {
// byte = dot[i];
// for(b=7; b>0; b--){
// if(byte & (1<<b)) {
// lcd_draw_point(x+7-b, y+i, 0xffffffff); //显示白色
// }else {
// lcd_draw_point(x+7-b, y+i, 0); //显示黑色
// }
// }
// }
// }
void lcd_draw_chinese(int x, int y, unsigned char *str) // 16*16
{
unsigned int area = str[0] - 0xA1;
unsigned int where = str[1] - 0xA1;
unsigned char *dot = fb_hzk + (area * 94 + where) * 32;
unsigned char byte;
int i,j,b;
for(i = 0; i < 16; i++) {
for(j = 0; j < 2; j++) {
byte = dot[i*2+j];
for(b = 7; b > 0; b--) {
if(byte & (1<<b)) {
lcd_draw_point(x+j*8+7-b, y+i, 0xffffffff); //显示白色
}else {
lcd_draw_point(x+j*8+7-b, y+i, 0); //显示黑色
}
}
}
}
}
void draw_bit_map(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 >= fb_var.xres || j >= fb_var.yres )
continue;
//image[j][i] |= bitmap->buffer[q * bitmap->width + p];
lcd_draw_point(i, j, bitmap->buffer[q * bitmap->width + p]);
}
}
}
void lcd_draw_oneline_left(wchar_t *str, FT_Int x, FT_Int y, int fontsize)
{
int i;
pen.x = x * 64;
pen.y = (fb_var.yres - y) * 64;
for(i = 0; i < wcslen(str); i++){
FT_Set_Transform(face, NULL, &pen);
FT_Load_Char(face, str[i], FT_LOAD_RENDER);
draw_bit_map( &face->glyph->bitmap,
face->glyph->bitmap_left,
fb_var.yres - face->glyph->bitmap_top);
pen.x += face->glyph->advance.x;
//pen.y = (fb_var.yres - 80) * 64;
}
}
void lcd_draw_oneline_center(wchar_t *str, FT_Int y, int fontsize) //仅需要知道高度即可
{
int i;
TGlyph glyph;
//计算输入的字符串的bbox的大小
for(i = 0; i < wcslen(str); i++) {
glyph->
}
}
int main(int argc, char **argv)
{
wchar_t *chinese_str = L"繁ABCDEFG";
FT_Library library;
int i;
fd_fb = open("/dev/fb0", O_RDWR);
if(fd_fb < 0)
{
printf("can't open fb0\n");
return -1;
}
if(argc != 2) {
printf("Usage : %s <font file>\n", argv[0]);
}
//获取屏幕信息
if(ioctl(fd_fb, FBIOGET_VSCREENINFO, &fb_var))
{
printf("can't get fb_var\n");
return -1;
}
//获取固定信息
if(ioctl(fd_fb, FBIOGET_FSCREENINFO, &fb_fix))
{
printf("can't get fb_fix\n");
return -1;
}
line_width = fb_var.xres * fb_var.bits_per_pixel / 8;
pixel_width = fb_var.bits_per_pixel / 8;
sreen_size = fb_var.xres * fb_var.yres * fb_var.bits_per_pixel / 8;
fb_mem = (unsigned char *)mmap(NULL, sreen_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_fb, 0);
if(fb_mem == MAP_FAILED)
{
printf("can't mmap\n");
return -1;
}
//清屏
memset(fb_mem, 0, sreen_size);
//初始化freeType库
if(FT_Init_FreeType(&library))
{
printf("can't init freetype library\n");
return -1;
}
//创建face对象
if(FT_New_Face(library, argv[1], 0, &face))
{
printf("can't create face object\n");
return -1;
}
//设置字体大小
if(FT_Set_Pixel_Sizes(face, 24, 0))
{
printf("can't set font size\n");
return -1;
}
//设置char初始点 (80,80)
lcd_draw_oneline_left(chinese_str, 0, 80, 24);
//lcd_draw_ascii(fb_var.xres/2, fb_var.yres/2, 'A');
//printf("chinese code = %02x %02x \n", str[0], str[1]);
//lcd_draw_chinese(fb_var.xres/2+8, fb_var.yres/2, str);
return 0;
}