LCD上显示几行矢量文字

一、从左上角显示

1)先描画第一行
2)算出边框
在这里插入图片描述
下面在lcd左上角上显示两行字符

/* 清屏: 全部设为黑色 */
	memset(fbmem, 0, screen_size);
	 
	/* 显示矢量字体 */
	error = FT_Init_FreeType( &library );             
 
 	error = FT_New_Face( library, argv[1], 0, &face );
 	slot = face->glyph;
    FT_Set_Pixel_Sizes(face, 24, 0);

	/* 确定座标:
	 * lcd_x = 0
	 * lcd_y = 24
	 
	 * 笛卡尔座标系:
	 * x = lcd_x = 0
	 * y = var.yres - lcd_y = var.yres - 24
	 */
	
	pen.x = 0 * 64;				//设置原点坐标,这个坐标是笛卡尔的坐标,
	pen.y = (var.yres - 24) * 64;
  
  

	for(i = 0; i < wcslen(wstr1); i++)	//在for循环中一次取出要显示的字符的位图
	{
	
		/* set transformation */
	    FT_Set_Transform( face, 0, &pen);		//设置转化参数
		 /* load glyph image into the slot (erase previous one) */
	    error = FT_Load_Char( face, wstr1[i], FT_LOAD_RENDER );	//根据unicode码加载glpyh并转换为位图
		if (error)
		{
			printf("FT_Load_Char error\n");
			return -1;
		}
		error = FT_Get_Glyph( face->glyph, &glyph );	//获取得到的当前的glpyh位图
		if (error)
		{
			printf("FT_Get_Glyph error!\n");
			return -1;
		}

		FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox );//得到glpyh变量里的bbox参数,这个参数记录了位图的xmin,
																//yMin等参数信息,获取它可以判定下一行的原点位置
		if (line_box_ymin > bbox.yMin)				
			line_box_ymin = bbox.yMin;
		if (line_box_ymax < bbox.yMax)
			line_box_ymax = bbox.yMax;
			
		
		draw_bitmap( &slot->bitmap,
	                 slot->bitmap_left,
	                 var.yres - slot->bitmap_top);

	    pen.x += slot->advance.x;
			
	}

	
	/* 确定座标:		下面显示的是第二行的数据,第二行的x坐标还是0,
	 * lcd_x = 0		y坐标是根据bbox确定的,这里假设加上24
	 * lcd_y = line_box_ymax - line_box_ymin + 24
	 
	 * 笛卡尔座标系:
	 * x = lcd_x = 0
	 * y = var.yres - lcd_y = var.yres - (line_box_ymax - line_box_ymin + 24)
	 */
	
	pen.x = 0 * 64;			//重新设置第二行的数据坐标
	pen.y = (var.yres - (line_box_ymax - line_box_ymin + 24)) * 64;
  
  

	for(i = 0; i < wcslen(wstr2); i++)
	{
	
		/* set transformation */
	    FT_Set_Transform( face, 0, &pen);
		 /* load glyph image into the slot (erase previous one) */
	    error = FT_Load_Char( face, wstr2[i], FT_LOAD_RENDER );
		if (error)
		{
			printf("FT_Load_Char error\n");
			return -1;
		}
		error = FT_Get_Glyph( face->glyph, &glyph );
		if (error)
		{
			printf("FT_Get_Glyph error!\n");
			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( &slot->bitmap,
	                 slot->bitmap_left,
	                 var.yres - slot->bitmap_top);

	    pen.x += slot->advance.x;
			
	}
	
	return 0;

在这里插入图片描述

二、居中显示
1)先算出边框
2)再确定代码并描画

main.c

/* 清屏: 全部设为黑色 */
	memset(fbmem, 0, screen_size);
	 
	/* 显示矢量字体 */
	error = FT_Init_FreeType( &library );             
 
 	error = FT_New_Face( library, argv[1], 0, &face );
 	slot = face->glyph;
    FT_Set_Pixel_Sizes(face, 24, 0);

	/* 显示第一行字符 */

	
	//glyphs是一个TGlyph类型的数组,用来存放需要显示的字符的glyph
	//Get_Glyphs_Frm_Wstr这个函数是自己实现的,从face文件中根据wstr1的unicode码找到glyph,
	//并保存到glyphs数组中,此函数的返回值是数组中的glyph的个数,也就是要显示的字符的个数
	num_glyphs = Get_Glyphs_Frm_Wstr(face, wstr1, glyphs);

	//此函数自己实现,用来算出第一行显示的字符的边框,方便计算下一行的原点位置
	compute_string_bbox(glyphs, num_glyphs, &bbox);
	line_box_width  = bbox.xMax - bbox.xMin;
	line_box_height = bbox.yMax - bbox.yMin;

	pen.x = (var.xres - line_box_width)/2 * 64;		//设置要显示的位置,这里子显示到屏幕的中间
	pen.y = (var.yres - line_box_height)/2 * 64;

	//显示第一行字符,此函数自己实现
	Draw_Glyphs(glyphs, num_glyphs, pen);
	

 	 /* 显示第二行字符 */  
  
	 num_glyphs = Get_Glyphs_Frm_Wstr(face, wstr2, glyphs);
	 
	 compute_string_bbox(glyphs, num_glyphs, &bbox);
	 line_box_width  = bbox.xMax - bbox.xMin;
	 line_box_height = 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;

Get_Glyphs_Frm_Wstr函数实现

int Get_Glyphs_Frm_Wstr(FT_Face face, wchar_t * wstr, TGlyph glyphs[])
 {
	int n;
	PGlyph glyph = glyphs;
	int pen_x = 0;
	int pen_y = 0;
	int error;
	FT_GlyphSlot  slot = face->glyph;;

	for(n = 0; n < wcslen(wstr); n++)
	{
		//使用此函数根据wstr[n]的unicode码在face中找到glyph的索引值
		glyph->index = FT_Get_Char_Index( face, wstr[n]); 
		
		/* store current pen position */ 
		glyph->pos.x = pen_x; 	//指定显示的坐标
		glyph->pos.y = pen_y;
		
		/* load时是根据索引值把glyph放入插槽face->glyph */
		error = FT_Load_Glyph(face, glyph->index, FT_LOAD_DEFAULT);
		if ( error ) 
			continue;

		//上面的函数是加载了glyph值到插槽slot中,单数函数执行过后这个插槽中的值就会更换新成下一个值
		//因此FT_Get_Glyph函数能够保存并本次的glyph值,方便后面获取参数等操作
		error = FT_Get_Glyph(face->glyph, &glyph->image ); 
		if ( error ) 
			continue;
			/* 这使得glyph->image里含有位置信息 */
		FT_Glyph_Transform(glyph->image, 0, &glyph->pos );
		pen_x += slot->advance.x;  /* 1/64 point */

		/* increment number of glyphs */ 
		glyph++;	
	}
 }

compute_string_bbox函数实现计算出边框

void compute_string_bbox(TGlyph glyphs[], FT_UInt num_glyphs, FT_BBox *abbox )
 {
	FT_BBox bbox; 
	int n;
		
	bbox.xMin = bbox.yMin = 32000; 	//先把xMin、yMin等设置为一个较大的值
	bbox.xMax = bbox.yMax = -32000;

	for(n = 0; n < num_glyphs; n++)
	{
		FT_BBox glyph_bbox;
		//先得到CBOX,信息放入glyph_bbox变量中
		FT_Glyph_Get_CBox(glyphs[n].image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox );
		if (glyph_bbox.xMin < 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;
 }

Draw_Glyphs函数实现

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);
		//将glyph转化为位图
		error = FT_Glyph_To_Bitmap(&glyphs[n].image, FT_RENDER_MODE_NORMAL, 0, 1 ); 
		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 ); //最后释放数组
		}
	}
 }

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值