您的位置:首页 > 其它

在 tiny210 下显示 字母 ,汉字,方框, 宋体,图片。

2014-06-27 15:34 483 查看
在开发板上显示字母,汉字,方框,宋体等。 我这里大部分都是参考韦东山老师讲的。

这里只是为了测试lcd驱动并且从新总结下。

英文字母和汉字: 利用点阵画点。

画线和画框: 调用画线函数

宋体: 利用freetype 库

图片: 利用libjpeg 压缩jpeg 图片显示。

 

代码如下:

// lcd_test.c
// 显示 横线 竖线 框 字符 汉字 字体 图像等
#include <sys/mman.h>
#include <stdio.h>
#include "ascii 8_16.h"
#include <linux/fb.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <wchar.h>
#include <string.h>

#include <ft2build.h>
#include FT_FREETYPE_H

#include "jpeglib.h"
#include <setjmp.h>

int fb_fd;
int hzk_fd;
struct stat hzk_stat;
unsigned char *hzk_mem;

unsigned char *fb_mem;
struct fb_var_screeninfo var;	/* Current var */
struct fb_fix_screeninfo fix;	/* Current fix */

int x_res, y_res;
int line_length;
int screen_size;
int pixel_length;

// freetype relattived parameters
FT_Library    library;
FT_Face       face;
FT_GlyphSlot  slot;
FT_Matrix     matrix;                 /* transformation matrix */
FT_Vector     pen;                    /* untransformed origin  */
FT_Error      error;

wchar_t *wtext = L"中国neo";
unsigned int           n ;

/* 显示 jpeg 图片相关参数*/
struct jpeg_decompress_struct cinfo;
struct my_error_mgr jerr;
FILE * infile;		/* source file */
unsigned char *buffer;		/* Output row buffer */
int row_stride;		/* physical row width in output buffer */
struct my_error_mgr {
struct jpeg_error_mgr pub;	/* "public" fields */
};

void lcd_clear_display(unsigned int c)
{
memset(fb_mem , 0 , screen_size);
}
void show_put_pixel(int x ,int y , unsigned int color)
{
unsigned int *pen_32 = (unsigned int *)(fb_mem + y*line_length + x*pixel_length);
if(var.bits_per_pixel != 32)
{
printf(" sorry ! only support 32 bit\n");
return ;
}
*pen_32 = color ;
}

void lcd_put_line(int x1, int y1 , int x2, int y2 , unsigned int color)
{
int dx,dy,e;
dx=x2-x1;
dy=y2-y1;

if(dx>=0)
{
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 1/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
show_put_pixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else		// 2/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
show_put_pixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else		   // dy<0
{
dy=-dy;   // dy=abs(dy)

if(dx>=dy) // 8/8 octant
{
e=dy-dx/2;
while(x1<=x2)
{
show_put_pixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1+=1;
e+=dy;
}
}
else		// 7/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
show_put_pixel(x1,y1,color);
if(e>0){x1+=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
else //dx<0
{
dx=-dx;		//dx=abs(dx)
if(dy >= 0) // dy>=0
{
if(dx>=dy) // 4/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
show_put_pixel(x1,y1,color);
if(e>0){y1+=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else		// 3/8 octant
{
e=dx-dy/2;
while(y1<=y2)
{
show_put_pixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1+=1;
e+=dx;
}
}
}
else		   // dy<0
{
dy=-dy;   // dy=abs(dy)

if(dx>=dy) // 5/8 octant
{
e=dy-dx/2;
while(x1>=x2)
{
show_put_pixel(x1,y1,color);
if(e>0){y1-=1;e-=dx;}
x1-=1;
e+=dy;
}
}
else		// 6/8 octant
{
e=dx-dy/2;
while(y1>=y2)
{
show_put_pixel(x1,y1,color);
if(e>0){x1-=1;e-=dy;}
y1-=1;
e+=dx;
}
}
}
}
}
void lcd_put_ascii(int x, int y , unsigned char c)
{
int i,j;
unsigned char byte;
// 获得点阵的起始坐标
unsigned char *dots = (unsigned char*)&fontdata_8x16[c*16] ;
printf("dots \n");
for(i=0 ; i<16; i++)
{
byte = dots[i];
for(j=7;j>=0;j--)
{
if(byte & (1<<j))
show_put_pixel(x+(7-j),y+i,0xffffff);
else
show_put_pixel(x+(7-j),y+i,0);
}
}
}
void lcd_put_gbk(int x, int y, unsigned char *str )
{
int i, j,k ;
unsigned char byte;
// 根据汉字库找到 汉字 起始地址
unsigned int area  = str[0] - 0xA1;  // hzk16 点阵字体文件是从0xA1 0xA1 开始的
unsigned int where = str[1] - 0xA1;
unsigned char *dots = (hzk_mem + (area*94 + where)*32);

for(i=0; i< 16 ;i++)
{
for(j=0 ; j<2 ;j++)
{
byte = dots[i*2+j*1];  // 逐个处理每个字节
for(k=7 ; k>=0; k--)
{
if(byte & (1<<k))
{
show_put_pixel(x+(7-k)+j*8,y+i,0xffffff);
}
else
{
show_put_pixel(x+(7-k)+j*8,y+i,0);
}
}
}
}
}

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 >=x_res   || j >= x_res )
continue;

if(bitmap->buffer[q * bitmap->width + p] )
show_put_pixel(x+p , y+q ,  0xffffff);
else
show_put_pixel(x+p , y+q ,  0);
//     image[j][i] |= bitmap->buffer[q * bitmap->width + p];
}
}
}

int put_scanline_someplace(unsigned char* buffer , int starty , int startx  , int endx )
{
int iX;
unsigned int color;

if(starty >= y_res)
return -1;
if(startx >= x_res)
return -1;
if(endx >= x_res)
endx = x_res ;

for(iX=startx ; iX<endx ; iX++)
{
color = (*buffer << 16) + (*(buffer+1) << 8) + (*(buffer+2)) ;
buffer += 3;
show_put_pixel(iX ,starty , color );
}
return 0;
}

int  main(int argc , char **argv)
{
unsigned char str1[] = {0xd6 , 0xd0}; // 中
unsigned char str2[] = {0xb9 , 0xfa}; // 国
unsigned char str3[] =  "中" ; // 中
unsigned char str4[] =  "国"; // 国
int ret;

/* 打开 framebuffer */
fb_fd = open("dev/fb0" , O_RDWR);
if(fb_fd < 0)
{
printf("neo: cannot open the fb device\n");
return -1;
}

/*获得固定参数 和 变化参数 */
ret = ioctl(fb_fd , FBIOGET_VSCREENINFO , &var);
if(ret)
{
printf("neo: get FBIOGET_VSCREENINFO args error");
return -1 ;
}

ret = ioctl(fb_fd , FBIOGET_FSCREENINFO , &fix);
if(ret)
{
printf("neo: get FBIOGET_FSCREENINFO args error");
return -1 ;
}

line_length	 =  fix.line_length;
screen_size  =  fix.smem_len;
pixel_length =  var.bits_per_pixel / 8;
x_res = var.xres;
y_res = var.yres;

/* 映射 framebuffer 地址 */
fb_mem =  (unsigned char*)mmap(NULL, screen_size,PROT_READ | PROT_WRITE,MAP_SHARED,fb_fd, 0);

/*清屏*/
lcd_clear_display(0);

/*显示 字符  'H'*/
lcd_put_ascii(100,100,'H');

/* 画线 */
lcd_put_line(0,0,799,479, 0xffffff);

/* 画框 */
lcd_put_line(30,30,700,30, 0xffffff);
lcd_put_line(30,30,30,300, 0xffffff);
lcd_put_line(700,30,700,300, 0xffffff);
lcd_put_line(30,300,700,300, 0xffffff);

/* 显示汉字  中国*/
hzk_fd  = open("HZK16" , O_RDWR); // 打开汉字库
ret = fstat(hzk_fd, &hzk_stat); // 获得汉字库大小
if(ret)
{
printf("can't  open the hanziku\n");
}
hzk_mem =  (unsigned char*)mmap(NULL, hzk_stat.st_size,PROT_READ | PROT_WRITE,MAP_SHARED,hzk_fd, 0);

printf("打印出 中国的 GBk code \n");
printf("GBK code :  %x , %x  , %x ,%x \n" , str1[0] , str1[1] ,str2[0] , str2[1] );
printf("GBK code :  %x , %x  , %x ,%x \n" , str3[0] , str3[1] ,str4[0] , str4[1] );
lcd_put_gbk(250 ,200 , str1); // 此时中字采用 gbk码 保存的 所以为 d6 d0
lcd_put_gbk(500 ,200 , str2);

/*显示宋体中国*/
error = FT_Init_FreeType( &library );              /* initialize library */

error = FT_New_Face( library, "./simsun.ttc", 0, &face ); /* create face object */
slot = face->glyph;

error = FT_Set_Pixel_Sizes(face, 24, 0);    /* set font size */

/* the pen position in 26.6 cartesian space coordinates; */
/* start at (300,200) relative to the upper left corner  */
pen.x = 300 * 64;
pen.y = ( y_res - 200 ) * 64;

for ( n = 0; n < wcslen( wtext ); n++ )
{
/* set transformation */
FT_Set_Transform( face, 0, &pen );

/* load glyph image into the slot (erase previous one) */
error = FT_Load_Char( face, wtext
, FT_LOAD_RENDER );
if ( error )
continue;                 /* ignore errors */

/* now, draw to our target surface (convert position) */
draw_bitmap( &slot->bitmap,
slot->bitmap_left,
y_res - slot->bitmap_top );

/* increment pen position */
pen.x += slot->advance.x;
}

/*显示 图片*/
//  Allocate and initialize a JPEG decompression object.
cinfo.err = jpeg_std_error(&jerr.pub);
jpeg_create_decompress(&cinfo);

//  Specify the source of the compressed data (eg, a file).

if ((infile = fopen("1.jpg", "rb")) == NULL) {
printf("can not open the jpeg file \n");
return -1;
}

jpeg_stdio_src(&cinfo, infile);

// 3. Call jpeg_read_header() to obtain image info.
jpeg_read_header(&cinfo, 1);

//  4. Set parameters for decompression.
printf("enter scale M/N:\n");
scanf("%d/%d",&cinfo.scale_num, &cinfo.scale_denom);
printf("scale to : %d/%d\n", cinfo.scale_num, cinfo.scale_denom);

//  5. jpeg_start_decompress(...);
jpeg_start_decompress(&cinfo);

/* 输出的图象的信息 */
988f

printf("output_width = %d\n", cinfo.output_width);
printf("output_height = %d\n", cinfo.output_height);
printf("output_components = %d\n", cinfo.output_components);

//  6. deal everyline data

row_stride = cinfo.output_width * cinfo.output_components;

buffer = malloc(row_stride);

while (cinfo.output_scanline < cinfo.output_height)
{
jpeg_read_scanlines(&cinfo, &buffer, 1);
put_scanline_someplace(&buffer[0], cinfo.output_scanline , 0 ,cinfo.output_width); // 显示
}

/* Step 7: Finish decompression */
jpeg_finish_decompress(&cinfo);
/* Step 8: Release JPEG decompression object */
jpeg_destroy_decompress(&cinfo);
fclose(infile);
free(buffer);

return 0;
}


 

 

附上图片,没有考虑美观:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐