欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

TQ210显示 字母 ,汉字,方框, 宋体,图片

程序员文章站 2022-03-22 16:45:21
...

在开发板上显示字母,汉字,方框,宋体等。 我这里大部分都是参考韦东山老师讲的。

这里只是为了测试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[n], 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);

	/* 输出的图象的信息 */
	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;
}
TQ210显示 字母 ,汉字,方框, 宋体,图片
相关标签: LCD