#pragma once #ifndef __lvgl_H #define __lvgl_H #include "stdlib.h" #include "string.h" #include #include #include /* Attribute to mark large constant arrays for example * font's bitmaps */ #define LV_ATTRIBUTE_LARGE_CONST /** Format of font character map. */ enum { LV_FONT_FMT_TXT_CMAP_FORMAT0_TINY, LV_FONT_FMT_TXT_CMAP_FORMAT0_FULL, LV_FONT_FMT_TXT_CMAP_SPARSE_TINY, LV_FONT_FMT_TXT_CMAP_SPARSE_FULL, }; typedef uint8_t lv_font_fmt_txt_cmap_type_t; typedef uint8_t lv_opa_t; /** This describes a glyph. */ 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; /**< 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; /* 将码点映射到 `glyph_dsc` 的结构体 * 支持多种格式以优化内存使用 * 详见 https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md */ typedef struct { /** 此范围的第一个Unicode字符 */ uint32_t range_start; /** 与此范围相关的Unicode字符数。 * 最后一个Unicode字符 = range_start + range_length - 1*/ uint16_t range_length; /** 此范围的第一个字形ID(`glyph_dsc` 的数组索引) */ uint16_t glyph_id_start; /* 根据规范,有4种格式: https://github.com/lvgl/lv_font_conv/blob/master/doc/font_spec.md 为简单起见引入“相对码点”: rcp = codepoint - range_start 和一个搜索函数: 在“数组”中搜索“值”并返回“值”的索引。 格式0 紧凑 unicode_list == NULL && glyph_id_ofs_list == NULL glyph_id = glyph_id_start + rcp 格式0 完整 unicode_list == NULL && glyph_id_ofs_list != NULL glyph_id = glyph_id_start + glyph_id_ofs_list[rcp] Fomat 紧凑 unicode_list != NULL && glyph_id_ofs_list == NULL glyph_id = glyph_id_start + search(unicode_list, rcp) Fomat 完整 unicode_list != NULL && glyph_id_ofs_list != NULL glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)] */ const uint16_t *unicode_list; /** 如果(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...),则为 `uint8_t *` * 如果(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...),则为 `uint16_t *` */ const void *glyph_id_ofs_list; /** `unicode_list` 和/或 `glyph_id_ofs_list` 的长度 */ uint16_t list_length; /** 此字符映射的类型 */ lv_font_fmt_txt_cmap_type_t type; } lv_font_fmt_txt_cmap_t; /* 描述字体的附加数据的结构体 */ typedef struct { /* 所有字形的位图 */ const uint8_t *glyph_bitmap; /* 描述字形 */ const lv_font_fmt_txt_glyph_dsc_t *glyph_dsc; /* 将字形映射到Unicode字符。 * `lv_font_cmap_fmt_txt_t` 变量的数组 */ const lv_font_fmt_txt_cmap_t *cmaps; /* 存储字距值。 * 可以是 `lv_font_fmt_txt_kern_pair_t *` 或 `lv_font_kern_classes_fmt_txt_t *` * 取决于 `kern_classes` */ const void *kern_dsc; /* 缩放字距值,12.4格式 */ uint16_t kern_scale; /* cmap表的数量 */ uint16_t cmap_num: 10; /* 每像素位数:1, 2, 3, 4, 8 */ uint16_t bpp: 4; /* `kern_dsc` 的类型 */ uint16_t kern_classes: 1; /* * 位图的存储格式 * 取自 `lv_font_fmt_txt_bitmap_format_t` */ uint16_t bitmap_format: 2; /* 缓存最后一个字母和其字形ID */ uint32_t last_letter; uint32_t last_glyph_id; } lv_font_fmt_txt_dsc_t; /* 坐标类型。应为 `int16_t`(或在极端情况下为 `int32_t`) */ typedef int16_t lv_coord_t; /** 描述字形属性的结构体 */ typedef struct { uint16_t adv_w; /**< 字形所需的空间。在此宽度后绘制下一个字形。8位整数,4位小数 */ uint16_t box_w; /**< 字形的包围框宽度 */ uint16_t box_h; /**< 字形的包围框高度 */ int16_t ofs_x; /**< 包围框的x偏移量 */ int16_t ofs_y; /**< 包围框的y偏移量 */ uint8_t bpp; /**< 每像素位数:1, 2, 4, 8 */ } lv_font_glyph_dsc_t; /** 描述字体的属性的结构体 */ typedef struct _lv_font_struct { /** 从字体中获取字形描述符 */ bool (*get_glyph_dsc)(const struct _lv_font_struct *, lv_font_glyph_dsc_t *, uint32_t letter, uint32_t letter_next); /** 从字体中获取字形的位图 */ const uint8_t *(*get_glyph_bitmap)(const struct _lv_font_struct *, uint32_t); /* 指向字体包中的字体的指针(必须具有相同的行高) */ lv_coord_t line_height; /**< 任何文本都适合的实际行高 */ lv_coord_t base_line; /**< 从行高顶部测量的基准线 */ uint8_t subpx: 2; /**< `lv_font_subpx_t` 的一个元素 */ int8_t underline_position; /**< 下划线顶部与基准线之间的距离(< 0 表示在基准线下方)*/ int8_t underline_thickness; /**< 下划线的厚度 */ void *dsc; /**< 在这里存储特定于实现或运行时数据或缓存 */ } lv_font_t; //#define NULL 0 /* see */ /** Bitmap formats*/ typedef enum { LV_FONT_FMT_TXT_PLAIN = 0, LV_FONT_FMT_TXT_COMPRESSED = 1, LV_FONT_FMT_TXT_COMPRESSED_NO_PREFILTER = 1, } lv_font_fmt_txt_bitmap_format_t; typedef uintptr_t lv_uintptr_t; /** 用于简单映射字距值对的结构体 */ typedef struct { /* 获取两个字符代码点之间的字距值: 1. 从 `lv_font_fmt_txt_cmap_t` 中获取 `glyph_id_left` 和 `glyph_id_right` 2. for(i = 0; i < pair_cnt * 2; i+2) if(gylph_ids[i] == glyph_id_left && gylph_ids[i+1] == glyph_id_right) return values[i / 2]; */ const void *glyph_ids; /* 存储字形ID对 */ const int8_t *values; /* 存储字距值 */ uint32_t pair_cnt: 24; /* 字距值对的数量 */ uint32_t glyph_ids_size: 2; /* 0: `glyph_ids` 存储为 `uint8_t`; 1: 存储为 `uint16_t` */ } lv_font_fmt_txt_kern_pair_t; /** 更复杂但更优化的基于类别的字距值存储结构体 */ typedef struct { /* 结构体用于获取两个字符代码点之间的字距值: 1. 从 `lv_font_fmt_txt_cmap_t` 中获取 `glyph_id_left` 和 `glyph_id_right` 2. 获取左侧和右侧字形的类别,分别为 `left_class` 和 `right_class` left_class = left_class_mapping[glyph_id_left]; right_class = right_class_mapping[glyph_id_right]; 3. value = class_pair_values[(left_class-1)*right_class_cnt + (right_class-1)] */ const int8_t *class_pair_values; /* 存储左侧类别数 * 右侧类别数的值 */ const uint8_t *left_class_mapping; /* 将字形ID映射到类别:索引 -> 字形ID -> 类别ID */ const uint8_t *right_class_mapping; /* 将字形ID映射到类别:索引 -> 字形ID -> 类别ID */ uint8_t left_class_cnt; /* 左侧类别数 */ uint8_t right_class_cnt; /* 右侧类别数 */ } lv_font_fmt_txt_kern_classes_t; #endif