Adafruit GFX Library字体规范

Adafruit GFX Library字体规范

陈拓 2021/06/29-2021/06/30

1. 概述

  • 什么是Adafruit GFX Library

看看Adafruit官方网站的介绍。

https://learn.adafruit.com/adafruit-gfx-graphics-library/overview

Arduino的Adafruit_GFX库为我们所有的LCD和OLED显示器(Adafruit的网站上有卖各种显示器)提供了通用语法和一组图形函数。这使得Arduino sketches (Arduino的内置例程称为sketches)可以很容易地在不同类型的显示器之间进行调整,任何新的功能、性能改进和错误修复都能很容易的呈现在所有显示器上。

  • Adafruit GFX库

Adafruit GFX Library在GitHub上开源:

https://github.com/adafruit/Adafruit-GFX-Library

这是用于我们所有显示器的核心图形库,它提供了一组通用的图形原语(点、线、圆等)。对于每个显示设备,它需要与特定于硬件的库配对(以处理较低级别的功能)。

Adafruit投入时间和资源提供此开源代码,请通过购买Adafruit的产品来支持Adafruit和开源硬件!

2. Adafruit GFX Library工具

有一些工具可以和Adafruit GFX Library一起使用。

  • Image2Code

Image2Code是一个小的Java GUI实用程序,用于将BMP图像文件转换为字节数组,可以用作Adafruit GFX库中的位图。

https://github.com/ehubin/Adafruit-GFX-Library/tree/master/Img2Code

  • drawXBitmap函数

您可以使用GIMP照片编辑器保存一个.xbm文件,并使用文件中保存的数组通过drawXBitmap函数绘制位图。

开源代码:

https://github.com/adafruit/Adafruit-GFX-Library/pull/31

  • 字体

Fonts文件夹包含用于最近(1.1及更高版本)Adafruit_GFX的位图字体。

  • fontconvert

fontconvert文件夹包含一个命令行工具,用于将TTF字体转换为Adafruit_GFX格式。

  • GFX字体定制工具

一个为Adafruit GFX库定制像素字体的小工具

https://tchapi.github.io/Adafruit-GFX-Font-Customiser/

开源代码:

https://github.com/tchapi/Adafruit-GFX-Font-Customiser

3. Adafruit GFX字体格式

Adafruit GFX字体有很多优点,节省空间,可变宽度的字体,有容易使用的字体转换和生成工具。但是Adafruit GFX字体格式的定义比较复杂,下面我们详细讲述Adafruit GFX字体的格式规范。我们以Adafruit-GFX-Library中的字体为例。

3.1 Adafruit-GFX-Library中字体

我们在这里主要关心的是Adafruit GFX字体。

Adafruit-GFX-Library中打开Fonts文件夹:

https://github.com/adafruit/Adafruit-GFX-Library

https://github.com/adafruit/Adafruit-GFX-Library/tree/master/Fonts

目前共有52种字体。下面我们看字体文件的构成。

3.2 字体文件的构成

打开一个字体文件,例如FreeMono18pt7b.h

一个字体文件从ASCII码0x20 ' '开始到0x7E '~'结束,共95个字符。

字体文件由3部分组成:

3.2.1 位图数据Bitmaps

首先是位图定义字节数组:

先看看下一小节的内容,结合glyph信息就可以知道字节数组怎样使用。

例如,字符0x22 '"'的宽是11,高是10,字节长度为25-11=14。我们从11开始取14个字节:

0xF1, 0xFE, 0x3F, 0xC7, 0xF8, 0xFF, 0x1E, 0xC3, 0x98, 0x33, 0x06, 0x60, 0xCC, 0x18

将这14个字节展开成二进制,用.代表0,用X代表1,宽度为11,逐行排列如下:

高度正好是10,这就是双引号"的字模。最后多出1个bit就不用了。

我们看到字模并不完美,这是因为Adafruit GFX字体是从TTF字体转换过来的,TTF是矢量字体,转换成点阵字体的过程中会有误差。如果你要求很高,可以自己修改。

3.2.2 字形Glyphs

接下来是一个glyph信息数组:

类型GFXglyph是结构体,定义如下:

typedef struct {
  uint16_t bitmapOffset; /// Pointer into GFXfont->bitmap
  uint8_t width;         /// Bitmap dimensions in pixels
  uint8_t height;        /// Bitmap dimensions in pixels
  uint8_t xAdvance;      /// Distance to advance cursor (x axis)
  int8_t xOffset;        /// X dist from cursor pos to UL corner
  int8_t yOffset;        /// Y dist from cursor pos to UL corner
} GFXglyph;
  • 位图数组的索引

GFXglyph的第一项是位图索引bitmapOffset。

我们从第一个字符索引开始看。

字符' '空格没有数据,所以第二个字符'!'的索引仍然为0。

第三个字符'"'的索引为11,说明第二个字符的字节长度为11。

第四个字符'#'的索引为25,说明第三个字符的字节长度为25-11=14

依此类推。

  • 字形的宽度和高度

GFXglyph第二和第三项是字形的宽度width和高度height。

例如:第四个字符0x23 '#'的宽度为14,高度为24。

  • 显示优化

GFXglyph第四项xAdvance用来优化显示效果。

例如第四个字符0x23 '#'的宽度为14,xAdvance为21。21-14=7

这样在显示的时候在字符的左边多出三个像素右边多出4个像,这样的空白便于阅读。

如有需要,这个值可以自己调整。

  • 字符的位置

GFXglyph的最后两个值xOffset和yOffset是像素便宜,用于定位字符。

通常显示器的坐标原点在左上角,如图左边的A。与之不同的是Adafruit GFX字体的原点坐标在左下角,如图右边的A。

所以如下图所示,xOffset和yOffset都会出现负值。

xOffset和yOffset是从光标位置到glyph位图左上角的像素偏移,在GFX坐标空间中,Y轴的原点在基线(Baseline)上,向上偏移是负值。xOffset的值多数情况下为正值,有时出现负值也是正常的。

如有需要,这两个值可以自己调整。

举前面的例子来说,字符双引号'"'的GFXglyph是{11, 11, 10, 21, 5, -20},其中宽是11,高是10,xOffset是5,yOffset是-20。我们用红色的.代表偏移,绘制出来是这样的:

xAdvance是21,21-11=10,左右各空5个像素,用绿色的.表示:

这是字符在显示器上的X方向占有26个像素,在Y方向占有20个像素,参考其他字符的高度最高有29,可以考虑将行高设置为30像素,这样我们在字符的上下分别再加5行像素,用蓝色的.表示:

这样就比较完美了。

关于行高在下一小节中有说明。

3.3.2 GFXfont

GFXfont是结构体,定义如下:

typedef struct {
  uint8_t  *bitmap;      /// Glyph bitmaps, concatenated
  GFXglyph *glyph;       /// Glyph array
  uint8_t   first;       /// ASCII extents (first char)
  uint8_t   last;        /// ASCII extents (last char)
  uint8_t   yAdvance;    /// Newline distance (y axis)
} GFXfont;

GFXfont是字体定义的最后一部分,是将所有内容连接在一起的结构。它包括指向位图数组的指针、指向glyph数据的指针和一些其他值。我们看看这三个其他值。

在我们的例子中,这三个值列为“0x20,0x7E,35”。0x20是第一个字符的ASCII码值,0x7E是最后个字符的ASCII码值。值“35”是字符显示时一行的参考垂直间距(也就是行高),这个值大于字符的高,而且大的比较多,所以一般不使用此值,而时根据字符的高在具体程序中自行定义一个行高。

3.3.4 PROGMEM关键字

PROGMEM关键字被Arduino和AVR编程使用,在ESP8266和ESP32的官方开发环境RTOS SDK和ESP-IDF中要删除。

参考文档

  1. Understanding the Font Specification
    https://learn.adafruit.com/creating-custom-symbol-font-for-adafruit-gfx-library/understanding-the-font-specification
  2. adafruit/Adafruit-GFX-Library
    https://github.com/adafruit/Adafruit-GFX-Library

猜你喜欢

转载自blog.csdn.net/chentuo2000/article/details/118369058