freetype_4_使用freetype显示多行文字

2023-11-14

freetype_4_使用freetype显示多行文字


从左往右显示
1、先描绘一行文字
2、取出该行文字的最大高度,以此为基准算出下一行的位置
3、再描绘另一行文字

根据上一篇文章中代码修改主函数部分

int main(int argv, char **argc)
{
	FT_Library	  library;
	FT_Face 	  face;
	FT_Vector	  pen;	
	wchar_t		 *str[] = {L"第一行",L"第二行"};
	FT_GlyphSlot  slot;
	int err;
	int n,l,lines = 2;
	FT_BBox bbox;
	FT_Glyph glyph;
	int y_min = 32*64,y_max = 0;
	
	if(argv != 2)
	{
		printf("Usage : %s <font_file>\r\n",argc[0]);
		return -1;
	}
	
	fd_fb = open("/dev/fb0",O_RDWR);
	if(fd_fb < 0)
	{
		printf("can't open /dev/fb0\r\n");
		return -1;
	}
	
	if(ioctl(fd_fb,FBIOGET_VSCREENINFO,&var))	
	{
		printf("can't get var\r\n");
		return -1;
	}	
	if(ioctl(fd_fb,FBIOGET_FSCREENINFO,&fix))
	{
		printf("can't get fix\r\n");
		return -1;	
	}	
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;	
	fbmem = (unsigned char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE , MAP_SHARED, fd_fb, 0);	
	if(fbmem == (unsigned char *)-1)
	{
		printf("can't mmap\r\n");
		return -1;
	}
	printf("xres:%d , yres:%d\r\n",var.xres,var.yres);
	pixel_width = var.bits_per_pixel / 8;
	line_width = var.xres * pixel_width;

	memset(fbmem,0x0,screen_size);

	err = FT_Init_FreeType(&library);			   	
	err = FT_New_Face(library, argc[1], 0, &face );	
	FT_Set_Pixel_Sizes(face,32,0);

	slot = face->glyph;
	
	pen.x = 0 * 64;
	pen.y = ( var.yres - 32 ) * 64;
	for(l = 0;l < lines;l++)
	{
		for(n = 0;n < wcslen(str[l]);n++)
		{
			FT_Set_Transform(face,0, &pen);
			err = FT_Load_Char(face, str[l][n],FT_LOAD_RENDER);
			if(err)
			{
				printf("FT load char err\r\n");
				return -1;
			}		
			FT_Get_Glyph(slot,&glyph);
			if(err)
			{
				printf("FT get glyph err\r\n");
				return -1;
			}	
			FT_Glyph_Get_CBox(glyph,FT_GLYPH_BBOX_TRUNCATE,&bbox);
			if(bbox.yMin < y_min)
				y_min = bbox.yMin;
			if(bbox.yMax > y_max)
				y_max = bbox.yMax;
			draw_bitmap(&slot->bitmap,slot->bitmap_left,var.yres - slot->bitmap_top);
			pen.x += slot->advance.x;
		}	
		/* 显示下一行 */
		pen.x = 0 * 64;
		pen.y -= ( y_max - y_min ) * 64;
	}

	return 0;
}

居中显示
1、先算出欲描绘文字串的长度,得到起点
2、从起点开始描绘一行文字
3、取出该行文字的最大高度,以此为基准描绘下一行

注意这里以笛卡尔坐标(0,0)为起点获取位图,描绘时再用pen根据偏移算出实际地址
定义宏

#define MAX_GLYPHS 100

声明结构体

typedef struct  TGlyph_
{
  FT_UInt    index;  /* glyph index                  */
  FT_Vector  pos;    /* glyph origin on the baseline */
  FT_Glyph   image;  /* glyph image                  */
} TGlyph, *PGlyph;

根据上面代码修改

int main( int argv, char **argc )
{
	FT_Library	  library;
	FT_Face 	  face;
	FT_Vector	  pen;	
	wchar_t		 *str[] = {L"第一行",L"第二行"};
	int err;
	int n,l,lines = 2;
	FT_BBox bbox;
	
	TGlyph        glyphs[MAX_GLYPHS];  /* glyphs table */
	PGlyph        glyph;               /* current glyph in table */
	FT_UInt       num_glyphs;	
	int line_box_width,line_box_height;
	
	
	if(argv != 2)
	{
		printf("Usage : %s <font_file>\r\n",argc[0]);
		return -1;
	}
	
	
	fd_fb = open("/dev/fb0",O_RDWR);
	if(fd_fb < 0)
	{
		printf("can't open /dev/fb0\r\n");
		return -1;
	}
	
	if(ioctl(fd_fb,FBIOGET_VSCREENINFO,&var))	
	{
		printf("can't get var\r\n");
		return -1;
	}	
	if(ioctl(fd_fb,FBIOGET_FSCREENINFO,&fix))
	{
		printf("can't get fix\r\n");
		return -1;	
	}	
	screen_size = var.xres * var.yres * var.bits_per_pixel / 8;	
	fbmem = (unsigned char *)mmap(NULL,screen_size,PROT_READ | PROT_WRITE , MAP_SHARED, fd_fb, 0);	
	if(fbmem == (unsigned char *)-1)
	{
		printf("can't mmap\r\n");
		return -1;
	}
	printf("xres:%d , yres:%d\r\n",var.xres,var.yres);
	pixel_width = var.bits_per_pixel / 8;
	line_width = var.xres * pixel_width;

	memset(fbmem,0x0,screen_size);

	err = FT_Init_FreeType(&library);			   	
	err = FT_New_Face(library, argc[1], 0, &face );	
	FT_Set_Pixel_Sizes(face,32,0);

	slot = face->glyph;
	
	pen.x = 0;
	pen.y = ( var.yres / 2 + 32 ) * 64;		

	for(l = 0;l < lines;l++)
	{
		num_glyphs = Get_Glyph(face,str[l],glyphs);
		Compute_Str_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 -=  line_box_height * 64;

		Draw_Glyphs(glyphs,num_glyphs,pen);
	}
	
	return 0;
}

定义一个函数获取glyph

int Get_Glyph(FT_Face face,wchar_t *str,TGlyph glyphs[])
{
	int i;
	PGlyph glyph = glyphs;	
	FT_Vector pen;
	int error;
	
	
	pen.x = pen.y = 0;
	for(i = 0;i < wcslen(str);i++)
	{
		glyph->index = FT_Get_Char_Index(face,str[i]);
		
		glyph->pos.x = pen.x;
		glyph->pos.y = pen.y;

		error = FT_Load_Glyph( face, glyph->index, FT_LOAD_DEFAULT );
		if ( error ) continue;

		error = FT_Get_Glyph( face->glyph, &glyph->image );
		if ( error ) continue;

		FT_Glyph_Transform( glyph->image, 0, &glyph->pos );

		pen.x += face->glyph->advance.x ;

		glyph++;		
	}
	return (glyph - glyphs);
}

定义一个函数计算BBOX参数

void Compute_Str_BBox( TGlyph glyphs[], FT_UInt num_glyphs, FT_BBox *abbox )
{
	FT_BBox bbox;
	int i;

	bbox.xMin = bbox.yMin =  32000;
	bbox.xMax = bbox.yMax = -32000;
	
	for(i = 0;i < num_glyphs;i++)
	{
		FT_BBox  glyph_bbox;
		FT_Glyph_Get_CBox( glyphs[i].image, FT_GLYPH_BBOX_TRUNCATE, &glyph_bbox );

		if (glyph_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;
}

定义一个函数描绘一行文字

void Draw_Glyphs( TGlyph glyphs[], FT_UInt num_glyphs, FT_Vector pen )
{
	int i;
	FT_BBox bbox;
	int error;
	
	for(i = 0;i < num_glyphs;i++)
	{
		FT_Glyph_Transform( glyphs[i].image, 0, &pen );
		
		error = FT_Glyph_To_Bitmap( &glyphs[i].image, FT_RENDER_MODE_NORMAL, 0, 1 ); 		
		if(error)	continue;
		
		FT_BitmapGlyph bit = (FT_BitmapGlyph) glyphs[i].image;
		draw_bitmap( &bit->bitmap, bit->left, var.yres - bit->top );
		//pen.x += glyphs[i].image.advance.x;
		//pen.y += glyphs[i].image.advance.y;

		FT_Done_Glyph( glyphs[i].image );				
	}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

freetype_4_使用freetype显示多行文字 的相关文章

  • StringIndexOutOfBoundsException: String index out of range: 458

    报错信息 org springframework dao TransientDataAccessResourceException Error updating database Cause java sql SQLException ja
  • Week 2 Git & Github 6: Rollback

    git revert HEAD 回退最新的一次commit 但是并不会撤销之前的commit记录 只是提交一次新的commit 将文件内容修改到上次commit之前的样子 到这里 我们已经学完了几乎所有的撤销更改的命令了 包括 git ch
  • 如何使用万用表测量二极管的阻值

    如何使用万用表测量二极管的阻值 1 测量时 选用万用表的 欧姆 挡 一般用R x100或R xlk挡 而不用Rx1或R x10k挡 因为Rxl挡的电流太大 容易烧坏二极管 R xlok挡的内电源电压太大 易击穿二极管 2 将两表棒分别接在二
  • 在MacOS下使用Fiddler抓包

    在MacOS下使用Fiddler抓包 在MacOS下使用Fiddler抓包 有两种方式 分别是安装Mac版的Fiddler 或者是用虚拟机 安装Windows系统 在Windows系统下运行Fiddler对Mac系统中的内容进行抓包 Mac
  • AES128加密算法的实现(C/Java/C#)

    最近项目中有一个需求 实现AES128的加密算法 用于硬件和平台的通信 硬件加密部分使用C语言完成 平台有两种不同的环境 java Linux 和C Windows 在网上搜集了一些资料 有人实现过纯C代码的AES加密解密算法 这样实际上有
  • Java 新特性 UpdateWrapper-(修改指定字段)

    UpdateWrapper的使用 UpdateWrapper的使用 修改指定id的名字 可在后增加条件 常用的连接条件 UpdateWrapper的使用 QueryWrapperLambdaQueryWrapper 条件查询 修改指定id的
  • 在 WebStorm 中开发 uni-app

    代码已上传至github github代码地址 https github com Miofly mio git CLI 工程 全局安装 vue cli 3 x 如已安装请跳过此步骤 npm install g vue cli 通过 CLI
  • JavaScript 常见鼠标事件

    常见鼠标事件类型1 1 click鼠标左键点击 2 mousedown 鼠标按下时触发 3 mouseup 鼠标弹起时触发 4 mousemove move移动 鼠标在固定的位置一移动就触发移动 就触发 5 mouseenter 鼠标移入触
  • Qt 识别 DM 码

    Qt 识别 DM 码 下载libdmtx 添加源码到Qt 工程 生成一维码 二维码 识别普通二维码网上库很多 这个库专门识别 DM码 下载libdmtx https github com dmtx libdmtx 添加源码到Qt 工程 li
  • 前程无忧guid、acw_sc__v2

    文章目录 声明 目标网站 acw sc v2分析 python调用测试 话外拓展 风控浅析 往期逆向文章推荐 声明 本文章中所有内容仅供学习交流 严禁用于商业用途和非法用途 否则由此产生的一切后果均与作者无关 若有侵权 请私信我立即删除 目
  • 新型智能优化算法——海鸥优化算法(基于Matlab代码实现)

    目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 1 概述 2019 年 Dhiman G等人提出了一种受自然界海鸥启发的新颖全局优化算法 海鸥优化算法 Seagull Optimization Algorithm SOA
  • 攻防世界RE练习

    攻防世界 一开始学习下re 产生了兴趣 game 这个题目在某个CTF平台做过了0 0 再做一遍 跟着WP 0 0 首先用ExeinfoPe或者Peid查壳 也可以使用file命令查看相关信息 32位程序 使用ida打开 F5反编译 程序逻
  • Blender基础操作:面操作细分、整体切分、挤出、内插、尖分、融并、切割、面的法向、填充等

    目录 1 面操作 进入 面选择 模式 选择一个面 2 面的挤出 3 内插面 4 尖分面 5 面的切割 6 面的法向normal 7 填充面 8 X Ray透视 1 面操作 进入 面选择 模式 选择一个面 4种操作手段 菜单 工具 右键菜单
  • WireShark_过滤语法

    WireShark 过滤语法 过滤IP 如来源IP或者目标IP等于某个IP 例子 ip src eq 192 168 1 107 or ip dst eq 192 168 1 107 或者 ip addr eq 192 168 1 107
  • python网络爬虫--selenium(6)--练习

    一 打开网页获取页面源码 from selenium webdriver chrome import webdriver 初始化 需要加载浏览器驱动 driver webdriver WebDriver executable path ch
  • 为解决cpu与主存的速度匹配可采用什么

    为解决cpu与主存的速度匹配可采用cache存储器 cache存储器是位于cpu和主存储器DRAM之间 规模较小 但速度很高的存储器 通常由静态存储器组成 静态存储器是位于cpu与内存间的一种容量较小但速度很高的存储器 为解决CPU和主存的
  • 计算机中丢失msvcp120.dll是什么意思,电脑提示msvcp120.dll丢失怎么办

    一些朋友在使用电脑的过程中 可能会遇到 msvcp120 dll丢失 的情况 那电脑提示msvcp120 dll丢失怎么办呢 碰到了这种情况不用慌 下面和大家分享电脑提示msvcp120 dll丢失解决方法 电脑提示msvcp120 dll
  • 完整教程:设计一款小巧但强大的传感器

    由IEEE制定的新型单对以太网 SPE 或10BASE T1L物理层标准 为传输设备运行状况信息实施状态监测 CbM 应用提供了新的连接解决方案 SPE提供共享电源和高带宽数据架构 可通过低成本双线电缆在超过1000米的距离实现10 Mbp
  • 实时汇率获取 解决跨域以及循环Ajax请求

    前端框架 ExtJs 币种代码 var currencys curCode USD curCode CNY curCode HKD setInterval function for var idx 0 len currencys lengt

随机推荐

  • Java 单链表

    package com abin lee tree test import com abin des algorithm common json jackson JsonUtil import java util concurrent at
  • vue动态表单封装

    需求 根据传参动态生成表单 例如搜索表格的表单 1 组件封装
  • Java--concurrent并发包下阻塞队列介绍

    JDK提供了7中阻塞队列 这里介绍其中3中 剩余的以此类推原理相同 1 ArrayBlockingQueue package com seeyon queue import java util concurrent ArrayBlockin
  • FastJson中JSONObject用法及常用方法总结

    人无远虑 必有近忧 1 什么是FastJson JSONObject fastjson是阿里巴巴的开源JSON解析库 它可以解析JSON格式的字符串 支持将Java Bean序列化为JSON字符串 也可以从JSON字符串反序列化到JavaB
  • 二本本科,银行外包开发工作 4 个月有余。聊聊外包公司工作的一些真实感受!...

    最近会更新一系列关于在外包工作的真实经历和感受的文章 挺多小伙伴都比较感兴趣的 文章内容都来自在外包公司工作的读者的真实经历 另外 不同的外包公司 不同的外包工作 不同的甲方等等因素都会影响每个人做外包工作的体验 希望大家在发表自己言论的时
  • [1128]commons-lang里面StringUtils方法说明以及案例

    文章目录 1 public static boolean isBlank String str 2 public static boolean isEmpty String str 3 public static boolean isNot
  • mysql Can’t connect to local MySQL server through socket ‘/var/lib/mysql/mysql.sock’

    mysql Can t connect to local MySQL server through socket var lib mysql mysql sock 今天在linux中安装了mysql但在连接时出现Can t connect
  • 【数据结构】CH3 栈和队列

    目录 前言 一 栈 1 栈的定义 1 相关概念 2 栈的抽象数据类型 2 栈的顺序存储结构及其基本运算的实现 1 顺序存储结构 2 初始化栈InitStack s 3 销毁栈DestroyStack s 4 判断栈是否为空StackEmpt
  • 蓝桥杯真题:测试次数

    这题是用动态规划去做的 参考 蓝桥杯 2018蓝桥初赛 测试次数 扔手机 动态规划 Miserable ccf的博客 CSDN博客 我们的目标是求取第n层 有m台手机下最优策略最坏情况下的测试数 我们定义dp i j 代表剩余i层 j台手机
  • Qt Creator + github copilot配置教程:AI编程新体验

    文章目录 前言 一 环境介绍 二 Copilot配置 1 安装nodejs 2 源码下载 方法a 代码克隆 方法b 直接下载源码包 3 路径配置 4 github copilot开通 三 安装Qt Creator 1 安装包下载 2 安装目
  • 五款实用的微信小程序(免费证件照)

    在这里给大家推荐几个平时常用的微信小程序 真心方便实用 绝对不是打广告 小米云证件照 目前很多证件照APP不是要收费 就是里面内置了许多广告 体验不佳 小米云证件照可以用三个词概况 免费 干净 无广告 懂的自然懂 扫描全能王 老牌的扫描工具
  • docker基础:联合文件系统

    首先docker的镜像是由一层一层的文件系统组成的 不同 Docker 容器就可以共享一些基础的文件系统层 同时再加上自己独有的改动层 大大提高了存储的效率 这个基础是联合文件系统 联合文件系统 UnionFS 是一种分层 轻量级并且高性能
  • 修改host方法

    打开路径 C Windows System32 drivers etc 将hosts文件拷贝出来修改之后放回去覆盖即可 想得到ip可以先ping一下那个域名 以下是一个例子 左边是ip 右边是域名 不用加 223 6 248 220 www
  • vue3+Element-plus el-select 下拉表格组件(2023-08-21 解决TSelectTable组件表单编辑回显设置defaultSelectVal 无效)

    2023 08 21 解决TSelectTable组件表单编辑回显设置defaultSelectVal 无效 2023 06 28 TSelectTable组件新增查询条件 效果如下 一 最终效果 二 代码示例
  • 【故障处理】EXP-00091 Exporting questionable statistics

    数据库平台 soalris10 数据库版本 9i 日期 2013 2 19 项目 关键字 1 Exp 00091 2 Exp 问题 使用exp导出时 出现错误 分析 oracle10g oerr exp 00091 00091 00000
  • Python报错No module named 'cv2'

    import cv2 Python运行过程中报错No module named cv2 Traceback most recent call last File Users congjam PycharmProjects Jam Test
  • python uwsgi_Python/WSGI应用快速入门

    Python WSGI应用快速入门 这个快速入门将会告诉你如何部署简单的WSGI应用和常见的web框架 这里 Python指的是CPython 对于PyPy 你需要使用特定的插件 PyPy插件 Jython支持正在开发中 注解 要遵循此快速
  • mysql表分区

    1 分表与表分区的区别 1 1 关于分表 分表是将一个大表分为几个或是多个小表 例如 table 1每天有1Kw的数据量 table 1随便时间的增长会越来越大 最终达到mysql表的极限 在这种比较极端的情况下 我们可以考虑对table
  • Android 路由框架ARouter源码解析

    作者 小马快跑 我们知道在使用ARouter时 需要在build config里配置 annotationProcessor com alibaba arouter compiler 1 2 2 并且知道annotationProcesso
  • freetype_4_使用freetype显示多行文字

    freetype 4 使用freetype显示多行文字 从左往右显示 1 先描绘一行文字 2 取出该行文字的最大高度 以此为基准算出下一行的位置 3 再描绘另一行文字 根据上一篇文章中代码修改主函数部分 int main int argv