title: freetype 字形解析

date: 2019/3/7 20:17:46

toc: true

freetype 字形解析

字体管理

管理字形,这里可以拆分为两个部分,一部分为管理字距,一部分为有效数据(位图信息).

比如字母g,蓝色框里的是有效的位图信息,但是排版的时候,是需要考虑字距的,否则虽然不重叠,但是不太好看.

数据结构

这里记住一个点

我们一般都是先转换到字符到字形槽,然后从字形槽提取位图,提取边界bbox

https://www.freetype.org/freetype2/docs/reference/ft2-index.html

这里有两个结构去描述

位图描述

  typedef struct  FT_Bitmap_
{
unsigned int rows;
unsigned int width;
int pitch;
unsigned char* buffer;
unsigned short num_grays;
unsigned char pixel_mode;
unsigned char palette_mode;
void* palette; } FT_Bitmap;

位图的定位点描述在字形槽里

  //字形槽
typedef struct FT_GlyphSlotRec_
{
FT_Library library;
FT_Face face;
FT_GlyphSlot next;
FT_UInt reserved; /* retained for binary compatibility */
FT_Generic generic; FT_Glyph_Metrics metrics;
FT_Fixed linearHoriAdvance;
FT_Fixed linearVertAdvance;
FT_Vector advance; //下个边界的原点 FT_Glyph_Format format; FT_Bitmap bitmap; //位图的描述
FT_Int bitmap_left; //位图的左上角点
FT_Int bitmap_top; //位图的左上角点 FT_Outline outline; FT_UInt num_subglyphs;
FT_SubGlyph subglyphs; void* control_data;
long control_len; FT_Pos lsb_delta;
FT_Pos rsb_delta; void* other; FT_Slot_Internal internal; } FT_GlyphSlotRec;

位置的边界需要去手动获取

这里的参数是FT_Glyph glyph,可以由face中的槽来转换

//从face的字形槽中取得字形
//FT_EXPORT( FT_Error )FT_Get_Glyph( FT_GlyphSlot slot,FT_Glyph *aglyph );
//字形描述
typedef struct FT_GlyphRec_
{
FT_Library library;
const FT_Glyph_Class* clazz;
FT_Glyph_Format format;
FT_Vector advance; } FT_GlyphRec;
error = FT_Get_Glyph( face->glyph, &glyph ); //从字形中取得bbox边界
FT_Glyph_Get_CBox( glyph, FT_GLYPH_BBOX_TRUNCATE, &bbox );
  FT_EXPORT( void )
FT_Glyph_Get_CBox( FT_Glyph glyph,
FT_UInt bbox_mode,
FT_BBox *acbox ); //传入参数
typedef struct FT_GlyphRec_
{
FT_Library library;
const FT_Glyph_Class* clazz;
FT_Glyph_Format format;
FT_Vector advance; } FT_GlyphRec;
// 传出参数
typedef struct FT_BBox_
{
FT_Pos xMin, yMin;
FT_Pos xMax, yMax; } FT_BBox;

字体抽象

刚开始我想抽象出位图信息



每个像素的bpp
换行像素位置
位图数据地址

那么除非我自己去控制字距,同时需要统计这一行的高度,来确定下一行文字的位置,但是这可能会排版成拥挤的上对齐,或者手动计算位图的大小,去布局,比如先设计一个32*32的边界,然后根据这个位图的大小居中摆放…想想就麻烦,而且这样的话设计字体旋转就没辙了

再仔细看下freetype的布局,其实是创建了一个布局,接着再看下旋转,我们实际刷新数据的时候,一般还是从左到右,从上到下刷新点,没有颜色的数据应该不去刷新,我们看下之前的字体旋转,可以发现是遮挡了的,所以遇到没有颜色的数据,应该去跳过这些点,而不是去绘图.

蓝色框是点阵图,我们刷新像素的位置

红色框是边界,用来描述布局的

我们之前的绘图是这样的

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 >= var.xres || j >= var.yres )
continue; // 添加下面这句话即可
// if(bitmap->buffer[q * bitmap->width + p])
lcd_put_pixel(i,j,bitmap->buffer[q * bitmap->width + p]);
}
}
}

这里对所有点都进行重绘,所以理论上应该会有字符的遮盖,上一节的实验也确实如此,可以看到h会把a遮挡了

修改下代码,判断如果没有颜色,则不需要描点即可,这里可以设置freetype的bpp是1即可,具体字体的颜色另外绘图指定即可.

freetype 字形解析的更多相关文章

  1. 我所理解的Cocos2d-x

    我所理解的Cocos2d-x(完全基于Cocos2d-x3.0,深度剖析计算机图形学,OpenGL ES及游戏引擎架构,全面提升游戏开发相关知识) 秦春林 著   ISBN 978-7-121-246 ...

  2. freetypeLCD显示

    目录 freetypeLCD显示 安装交叉编译环境 配置 头文件和库的位置 编译安装 复制到PC编译工具链 复制到文件系统 运行测试 LCD显示 编码转换问题 简单显示 角度旋转 换行显示 居中显示 ...

  3. C#+OpenGL+FreeType显示3D文字(1) - 从TTF文件导出字形贴图

    C#+OpenGL+FreeType显示3D文字(1) - 从TTF文件导出字形贴图 +BIT祝威+悄悄在此留下版了个权的信息说: 最近需要用OpenGL绘制文字,这是个很费时费力的事.一般的思路就是 ...

  4. 基于Qt的FreeType字体轮廓解析

    一.本文目的 以前的文档中.详细的介绍了FreeType开源字体引擎库的基础知识.基本用法.但并未详细的阐明在TurboCG中.是如何解析出一个文字的轮廓的,本文集中阐述.怎么样使用FreeType开 ...

  5. FreeType 管理字形

    转自:http://blog.csdn.net/hgl868/article/details/7254687 1.字形度量 顾名思义,字形度量是对应每一个字形的特定距离,以此描述如何对文本排版.    ...

  6. 解析 Qt 字库移植并能显示中文 (上篇)

    原文http://mobile.51cto.com/symbian-272552.htm 本文介绍的是Qt 字库移植并能显示中文,需要的字体库文件,一般是多个.具体移植那一个,看你使用的字库是什么了, ...

  7. CSharpGL(28)得到高精度可定制字形贴图的极简方法

    CSharpGL(28)得到高精度可定制字形贴图的极简方法 回顾 以前我用SharpFont实现了解析TTF文件从而获取字形贴图的功能,并最终实现了用OpenGL渲染文字. 使用SharpFont,美 ...

  8. C#+OpenGL+FreeType显示3D文字(3) - 用PointSprite绘制文字

    C#+OpenGL+FreeType显示3D文字(3) - 用PointSprite绘制文字 上一篇实现了把文字绘制到OpenGL窗口,但实质上只是把含有文字的贴图贴到矩形模型上.本篇我们介绍用Poi ...

  9. C#+OpenGL+FreeType显示3D文字(2) - 用GLSL+VBO绘制文字

    C#+OpenGL+FreeType显示3D文字(2) - 用GLSL+VBO绘制文字 +BIT祝威+悄悄在此留下版了个权的信息说: 上一篇得到了字形贴图及其位置字典(可导出为XML).本篇就利用此贴 ...

随机推荐

  1. 本地服务器硬件信息获取指令wmic

    获取BIOS序列号 wmic bios list full | find "SerialNumber" SerialNumber=P50168VB 获取CPUID(WIN32_PR ...

  2. FelxCell常用属性设置(未完待续......)

    this.grid1.AllowUserPaste//返回或设置是否允许用户粘贴文字和格式 grid1.Cell(Rows, 1).WrapText = true;//设置单元格自动换行

  3. servlet之转发与重定向的区别

    转发(服务器端跳转):  一次请求 <jsp:forward> request.getRequestDispatcher("new.jsp").forward(requ ...

  4. c/c++ 网络编程 read,write函数深入理解

    read,write函数深入理解 1,服务端的write函数,可以指定发送数据的长度(第三个参数length) write(connfd, &buff[i], length); 2,客户端的r ...

  5. SQL server 2017使用教程

    1.安装: 从https://www.microsoft.com/en-us/sql-server/sql-server-downloads官网下载sql server2017试用版 180天 安装完 ...

  6. Mongo C# Driver 聚合使用---深入浅出

    聚合查询结构体系 ​ 我们都知道Mongo中聚合是由$match,$project等聚合项组成,所以在C# Driver中具有两种类型:聚合管道(PipelineDefinition)和聚合管道项(I ...

  7. DirectX11 With Windows SDK--10 摄像机类

    前言 DirectX11 With Windows SDK完整目录:http://www.cnblogs.com/X-Jun/p/9028764.html 由于考虑后续的项目需要有一个比较好的演示环境 ...

  8. 微信网页分享 jssdk config:invalid signature 签名错误

    invalid signature签名错误.建议按如下顺序检查: 确认签名算法正确,可用 http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=jsapisi ...

  9. Oracle timestamp类型转换成date类型

    今天需要根据时间判断,统一修改某一个字段的数据.然后打开数据库发现,时间类型为timestamp类型.如下: 然后呢,这对我不是喝口水就可以解决的问题吗? 解决方案如下:我需要改这张表某个字段的内容, ...

  10. linux上面sqlserver数据库的操作

    sqlserver2017可以安装到linux也不是什么新鲜事, centos安装好sqlserver后有一写操作 systemctl status mssql-server:查看sqlserver的 ...