TQ210 Display letters, Chinese characters, boxes, Song Dynasty, pictures

Display letters, Chinese characters, boxes, Song Dynasty, etc. on the development board. I mostly refer to what Mr. Wei Dongshan said here.

This is just to test the lcd driver and re-summarize it.

English letters and Chinese characters: Draw dots using dot matrix.

Line drawing and drawing frame: call the line drawing function

Arial: Utilize the freetype library

Image: Use libjpeg to compress jpeg image display.

Full code download

// lcd_test.c
// Display horizontal and vertical frame characters, Chinese font images, etc.
#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 state 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 relative 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 ;
 


/* Display jpeg image related parameters */
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;
	// Get the starting coordinates of the lattice
	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;
	// Find the starting address of Chinese characters according to the Chinese character library
	unsigned int area = str[0] - 0xA1; // hzk16 dot matrix font file starts from 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]; // process each byte one by one
			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;

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

	/* Get fixed parameters and variable parameters */
	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;

	
	/* map framebuffer address */
    fb_mem =  (unsigned char*)mmap(NULL, screen_size,PROT_READ | PROT_WRITE,MAP_SHARED,fb_fd, 0);
	

	/*Clear screen*/
	lcd_clear_display(0);
	
	/* display the character 'H' */
	lcd_put_ascii(100,100,'H');

	/* draw lines */
	lcd_put_line(0,0,799,479, 0xffffff);

	/* frame*/
	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);

	/* Display Chinese characters */	
	hzk_fd = open("HZK16" , O_RDWR); // Open Chinese character library
	ret = fstat(hzk_fd, &hzk_stat); // Get the size of the Chinese character library
	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("Print out Chinese 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); // At this time, the middle word is stored in gbk code, so it is d6 d0
	lcd_put_gbk(500 ,200 , str2);



	/* Display Song Chinese */
	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;
	}


	/*display image*/
//  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);

	/* output image information */
	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;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325731117&siteId=291194637