Format de police LVGL V8

Il existe principalement deux types d'informations stockées dans le fichier de police, l'une est le tableau de treillis de caractères et l'autre est les données du tableau d'encodage Unicode correspondant. Lorsque le micro-ordinateur monopuce analyse la police, il trouve le réseau de caractères correspondant selon le codage Unicode.

Les données matricielles du fichier de police généré par le format de police LVGL ne ressemblent pas aux polices que nous utilisons habituellement dans les micro-ordinateurs monopuce.
Tout d'abord, le nombre d'octets occupés par les données matricielles de chaque caractère n'est pas égal, comme les guillemets simples "," et les caractères "@", le nombre d'octets qu'ils occupent n'est pas égal, c'est pour économiser de l'espace et videz les caractères Les lignes et les colonnes n'ont pas été converties en matrice de points. Dans ce cas, d'autres informations sont nécessaires pour contrôler la position d'affichage des caractères. Par conséquent, en plus du tableau de treillis de caractères et du tableau Unicode, il existe un tableau important glyph_dsc[] dans les données de police.

Structure de police LVGL

uint8_t   glyph_bitmap[]; 					//字形屏幕像素映射(字符点阵数组,将字符中空的行和列的地方不转化为点阵)
lv_font_fmt_txt_glyph_dsc_t   glyph_dsc; 	//描述unicode偏移、字形大小、位置偏移
uint16_t   unicode_list_0; 				    //unicode 列表(字符映射)
lv_font_fmt_txt_cmap_t   cmaps; 			//cmaps收集 unicode 列表和字符偏移
lv_font_fmt_txt_dsc_t   font_dsc; 		    //字体描述,用于将上面的信息收集打包
lv_font_t   ch_word; 						//程序中 label 等组件可以使用的字库。

analyser les fichiers de polices

Le programme obtiendra d'abord le codage UTF-8 du caractère à afficher, puis convertira UTF-8 en codage non codé, puis recherchera l'index du codage Unicode correspondant dans le tableau Unicode du fichier de police, puis utilisera l'index pour recherchez le caractère correspondant dans les données glyph_dsc. Étant donné que l'Unicode est classé par ordre croissant, la méthode de recherche médiane peut être utilisée pour améliorer la vitesse de recherche.

profondeur de pixels bpp

La couleur d'un pixel est décrite par le nombre de bits de données présents dans l'ordinateur. Les ordinateurs utilisent des bits binaires pour représenter les données d'un pixel. Plus il y a de bits de données utilisés pour représenter un pixel, plus la valeur de couleur du pixel est riche et fine, et plus la profondeur de couleur est profonde.
Il existe plusieurs profondeurs de pixels : 1 bit, 2 bits, 4 bits, 8 bits, 16 bits, 24 bits, 32 bits.

Le bpp de la police peut être défini sur 1, 2 ou 4. Lorsqu'une valeur bpp plus grande est sélectionnée, les ressources de stockage flash requises augmenteront également de façon exponentielle, mais plus la valeur bpp est grande, plus le bord de la police dessinée est lisse sans Problèmes Rendre l'interface utilisateur de nos produits plus magnifique.
insérer la description de l'image ici
Pour les polices 1bpp : utilisez 1 bit pour représenter 1 point de pixel, chaque pixel n'a que deux états d'activation et de désactivation, et 1 caractère chinois occupe 256/8 = 32 octets. Pour les polices 2bpp : utilisez 2 bits pour représenter 1 point de pixel, réalisez le
sous -rendu en pixels, 1 caractère chinois occupe 256 2/8 = 64 octets d' espace
Pour les polices 4bpp : utilisez 4 bits pour représenter 1 pixel, réalisez un rendu sous-pixel, 1 caractère chinois occupe 256 4
/8 = 128 octets d' espace

Pixmap de l'écran de glyphe

//存储符号的图像
static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = {
    
    
    /* U+56DE "回" */
    0x0, 0x11, 0xfb, 0xc1, 0x40, 0x29, 0xe5, 0x24,
    0xa4, 0x94, 0xb2, 0x98, 0x50, 0xa, 0x1, 0x7f,
    0xa8, 0xc, 0x0, 0x0,
    /* U+6D41 "流" */
    0x1, 0x0, 0x1, 0x0, 0xc0, 0x0, 0x3f, 0xc0,
    0x8, 0x0, 0x24, 0x13, 0xfc, 0x8, 0x0, 0x12,
    0xa0, 0x25, 0x40, 0x92, 0x81, 0x25, 0x26, 0x4a,
    0x45, 0x14, 0x84, 0xf, 0x80,
    /* U+96EA "雪" */
    0x0, 0x60, 0x7e, 0x4, 0x20, 0x9f, 0xfe, 0x82,
    0x20, 0xeb, 0x0, 0x2e, 0xe, 0x80, 0x1, 0xe0,
    0x78, 0x80, 0xa, 0x7, 0xd0, 0x0, 0x40, 0xff,
    0x0,
    /* U+98CE "风" */
    0x0, 0x0, 0x23, 0xc0, 0x78, 0x80, 0x85, 0x1,
    0xa, 0x2, 0xa4, 0x4, 0xc8, 0x8, 0x90, 0x13,
    0x20, 0x49, 0x20, 0xa2, 0x49, 0x80, 0xa4, 0x0,
    0xc0, 0x0, 0x80, 0x0, 0x0
};

En observant le tableau de mappage de pixels de l'écran glyphe, on peut obtenir
que « retour » occupe 20 octets,
« flux » occupe 29 octets,
« neige » occupe 25 octets,
« vent » occupe 29 octets.

description de la police

//这描述了一个字形
typedef struct {
    
    
#if LV_FONT_FMT_TXT_LARGE == 0
    uint32_t bitmap_index : 20;     /**< 字符对应的字模数据索引   Start index of the bitmap. A font can be max 1 MB.*/
    uint32_t adv_w : 12;            /**< 字符宽度,在此宽度之后绘制下一个字形。8.4 format(存储real_value * 16)。                Draw the next glyph after this width. 8.4 format (real_value * 16 is stored).*/
    uint8_t box_w;                  /**< 字模宽度                Width of the glyph's bounding box*/
    uint8_t box_h;                  /**< 字模高度                Height of the glyph's bounding box*/
    int8_t ofs_x;                   /**< 字模水平方向偏移(右边为正向)      x offset of the bounding box*/
    int8_t ofs_y;                   /**< 字模竖直方向偏移(上边为正向)(当字符需要在基线以下显示时使用这个参数让字模下沉)y offset of the bounding box. Measured from the top of the line*/
#else
    uint32_t bitmap_index;          /**< Start index of the bitmap. A font can be max 4 GB.*/
    uint32_t adv_w;                 /**< Draw the next glyph after this width. 28.4 format (real_value * 16 is stored).*/
    uint16_t box_w;                 /**< Width of the glyph's bounding box*/
    uint16_t box_h;                 /**< Height of the glyph's bounding box*/
    int16_t ofs_x;                  /**< x offset of the bounding box*/
    int16_t ofs_y;                  /**< y offset of the bounding box. Measured from the top of the line*/
#endif
} lv_font_fmt_txt_glyph_dsc_t;
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
    
    
    {
    
    .bitmap_index = 0, .adv_w = 0, .box_w = 0, .box_h = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
    {
    
    .bitmap_index = 0, .adv_w = 256, .box_w = 11, .box_h = 14, .ofs_x = 3, .ofs_y = -1},       //回
    {
    
    .bitmap_index = 20, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 0, .ofs_y = -1},		//流
    {
    
    .bitmap_index = 49, .adv_w = 256, .box_w = 14, .box_h = 14, .ofs_x = 1, .ofs_y = -1},		//雪
    {
    
    .bitmap_index = 74, .adv_w = 256, .box_w = 15, .box_h = 15, .ofs_x = 1, .ofs_y = -2}		//风
};
  1. Membre bitmap_index :
    A partir du tableau glyph_dsc, on peut également obtenir à partir du tableau glyph_dsc que le mappage de pixels d'écran des glyphes de caractères chinois occupe des octets :
    l'index des données de glyphe correspondant au caractère "hui"index_bitmap=0
    L'index des données de police correspondant au caractère de "stream"index_bitmap=20, donc « Hui » occupe 20 octets
    Fonction : Selon ces données, le décalage de chaque caractère chinois dans le tableau de description de glyphe peut être localisé
  2. Membre adv_w :
    indique la largeur du caractère, après quoi le glyphe suivant est dessiné.
    Parce que la police 16*16 (256 pixels) est sélectionnée, après avoir dessiné 256 pixels, c'est le pixel de départ du glyphe suivant.
  3. Membres box_w et box_h
    largeur et hauteur de police
    insérer la description de l'image ici

structure cmaps

cmaps collecte les listes Unicode et les décalages de caractères

liste Unicode

static const uint16_t unicode_list_0[] = {
    
    
    0x0, 0x1663, 0x400c, 0x41f0
};

/* U+56DE "back" /, / U+6D41 "flow" /, / U+96EA "snow" /, / U+98CE "wind" */
Le codage Unicode minimum de "back" est 0x56DE =22238
" "Flux" Codage Unicode minimum 0x6D41 = 27969
"Neige" Codage Unicode minimum 0x96EA = 38634
"Vent" Codage Unicode maximum 0x98CE = 39118

Le tableau unicode_list_0 stocke le décalage d'Unicode par rapport au premier caractère Unicode

  • unicode_list_0[0] =0x0, indiquant que le décalage Unicode de "Hui" est de 0 par rapport à "Hui"
  • unicode_list_0[1] =0x1663, indiquant que le décalage Unicode de "stream" par rapport à "back" est de 0x1663
  • unicode_list_0[2] =0x400c, indiquant que le décalage Unicode de « neige » par rapport à « retour » est de 0x400c
  • unicode_list_0[3] =0x41f0, indiquant que le décalage Unicode de « vent » par rapport à « retour » est 0x41f0

Structure lv_font_fmt_txt_cmap_t analyse des membres cmaps

static const lv_font_fmt_txt_cmap_t cmaps[] =
{
    
    
    {
    
    
		.range_start = 22238, 
		.range_length = 16881, 
		.glyph_id_start = 1,
		.unicode_list = unicode_list_0, 
		.glyph_id_ofs_list = NULL, 
		.list_length = 4, 
		.type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY
    }
};
  1. Membre uint32_t range_start
    le premier caractère Unicode de cette plage, car "back" est le premier caractère, donc .range_start = 22238,

  2. Membre uint16_t range_length
    Nombre de caractères Unicode associés à cette plage.
    "Retour" est le premier caractère 22238, "vent" est le dernier caractère 39118, le dernier caractère Unicode = range_start + range_length - 1
    donc .range_length = 39118 - 22238 + 1 = 16881 ;

  3. Membre uint16_t glyph_id_start
    Le premier ID de glyphe de cette plage (l'index du tableau de ' glyph_dsc '), car l'index du tableau glyph_dsc est réservé (id = 0 réservé), donc glyph_id_start commence à 1.

  4. Le pointeur du membre uint16_t *unicode_list
    pointe vers unicode_list_0.

  5. membre nul *glyph_id_ofs_list

  6. membre uint16_t list_length
    longueur de 'unicode_list' et/ou 'glyph_id_ofs_list'

  7. Member lv_font_fmt_txt_cmap_type_t type
    Le type de mappage de caractères

structure font_dsc

lv_font_fmt_txt_dsc_t font_dsc; //Description de la police, utilisée pour collecter et regrouper les informations ci-dessus

//描述存储字体的附加数据
#if LV_VERSION_CHECK(8, 0, 0)
/*存储所有自定义的字体数据*/
static  lv_font_fmt_txt_glyph_cache_t cache;
static const lv_font_fmt_txt_dsc_t font_dsc = {
    
    
#else
static lv_font_fmt_txt_dsc_t font_dsc = {
    
    
#endif
    .glyph_bitmap = glyph_bitmap, 	//所有字形的位图
    .glyph_dsc = glyph_dsc,       	//描述符号
    .cmaps = cmaps,					//将字形映射到Unicode字符。' lv_font_cmap_fmt_txt_t '变量的数组
	//存储字距调整值
	.kern_dsc = NULL,	//可以是' lv_font_fmt_txt_kern_pair_t *或' lv_font_kern_classes_fmt_txt_t * '根据“kern_classes”
    .kern_scale = 0,     			//按12.4格式缩放kern值
    .cmap_num = 1,					//cmap表的个数
    .bpp = 1,						//像素深度bpp: 1, 2, 4
    .kern_classes = 0,     			//“kern dsc”类型
    .bitmap_format = 0,             //位图的存储格式为' lv_font_fmt_txt_bitmap_format_t '
#if LV_VERSION_CHECK(8, 0, 0)
    .cache = &cache					//缓存最后一个字母和字形id
#endif
};

Structure de la police ch_word

/*初始化公共通用字体描述符*/
#if LV_VERSION_CHECK(8, 0, 0)
const lv_font_t ch_word = {
    
    
#else
lv_font_t ch_word = {
    
    
#endif
    .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt,    	/*从自定义字体数据中获取字形数据的函数指针*/
    .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt,    	/*从自定义字体数据中获取字形位图的函数指针*/
    .line_height = 17,          						/*字体所需的最大行高*/
    .base_line = 3,             						/*从底线开始测量基线*/
#if !(LVGL_VERSION_MAJOR == 6 && LVGL_VERSION_MINOR == 0)
    .subpx = LV_FONT_SUBPX_NONE,                        /*位图可以放大3倍以实现亚像素渲染*/
#endif
#if LV_VERSION_CHECK(7, 4, 0) || LVGL_VERSION_MAJOR >= 8
    .underline_position = -4,                           /*下划线顶部与基线之间的距离(< 0表示基线以下)*/
    .underline_thickness = 1,							/*下划线的厚度*/
#endif
    .dsc = &font_dsc           /*自定义字体数据。将通过' get_glyph_bitmap/dsc '访问*/
};

Utilisation de la police

La bibliothèque de polices doit être déclarée avant d'être utilisée

LV_FONT_DECLARE(ch_word); //Déclarer la police ch_word

static lv_style_t style;
lv_style_set_text_font(&style,&ch_word);       //设置样式字体

Je suppose que tu aimes

Origine blog.csdn.net/m0_37187962/article/details/125577898
conseillé
Classement