2019-05-20 06:40:00 +02:00
|
|
|
/**
|
|
|
|
* @file lv_font.h
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
2019-05-24 06:24:31 +02:00
|
|
|
#ifndef LV_FONT_FMT_TXT_H
|
|
|
|
#define LV_FONT_FMT_TXT_H
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
extern "C" {
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/*********************
|
|
|
|
* INCLUDES
|
|
|
|
*********************/
|
|
|
|
#ifdef LV_CONF_INCLUDE_SIMPLE
|
|
|
|
#include "lv_conf.h"
|
|
|
|
#else
|
2019-06-06 05:55:17 +02:00
|
|
|
#include "../../../lv_conf.h"
|
2019-05-20 06:40:00 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdbool.h>
|
2019-06-06 05:55:17 +02:00
|
|
|
#include "lv_font.h"
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/*********************
|
|
|
|
* DEFINES
|
|
|
|
*********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* TYPEDEFS
|
|
|
|
**********************/
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** This describes a glyph. */
|
2019-05-20 06:40:00 +02:00
|
|
|
typedef struct
|
|
|
|
{
|
2019-07-05 06:11:49 +02:00
|
|
|
#if LV_FONT_FMT_TXT_LARGE == 0
|
2019-06-27 18:07:26 -04:00
|
|
|
uint32_t bitmap_index : 20; /**< Start index of the bitmap. A font can be max 1 MB. */
|
2019-07-05 06:11:49 +02:00
|
|
|
uint32_t adv_w :12; /**< Draw the next glyph after this width. 8.4 format (real_value * 16 is stored). */
|
|
|
|
#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). */
|
|
|
|
#endif
|
2019-06-27 18:07:26 -04:00
|
|
|
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*/
|
|
|
|
uint8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
|
2019-05-28 08:46:43 +02:00
|
|
|
}lv_font_fmt_txt_glyph_dsc_t;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
2019-05-28 08:06:15 +02:00
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** Format of font character map. */
|
2019-07-10 14:51:59 +02:00
|
|
|
enum {
|
2019-05-28 08:06:15 +02:00
|
|
|
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,
|
2019-07-10 14:51:59 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
typedef uint8_t lv_font_fmt_txt_cmap_type_t;
|
2019-05-28 08:06:15 +02:00
|
|
|
|
|
|
|
|
2019-05-20 06:40:00 +02:00
|
|
|
/* Map codepoints to a `glyph_dsc`s
|
|
|
|
* Several formats are supported to optimize memory usage
|
|
|
|
* See https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
|
|
|
*/
|
|
|
|
typedef struct {
|
2019-06-27 18:07:26 -04:00
|
|
|
/** First Unicode character for this range */
|
2019-05-20 06:40:00 +02:00
|
|
|
uint32_t range_start;
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** Number of Unicode characters related to this range.
|
2019-05-20 06:40:00 +02:00
|
|
|
* Last Unicode character = range_start + range_length - 1*/
|
|
|
|
uint16_t range_length;
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** First glyph ID (array index of `glyph_dsc`) for this range */
|
2019-05-20 06:40:00 +02:00
|
|
|
uint16_t glyph_id_start;
|
|
|
|
|
|
|
|
/*
|
|
|
|
According the specification there are 4 formats:
|
|
|
|
https://github.com/littlevgl/lv_font_conv/blob/master/doc/font_spec.md
|
|
|
|
|
|
|
|
For simplicity introduce "relative code point":
|
|
|
|
rcp = codepoint - range_start
|
|
|
|
|
|
|
|
and a search function:
|
|
|
|
search a "value" in an "array" and returns the index of "value".
|
|
|
|
|
|
|
|
Format 0 tiny
|
2019-05-24 06:24:31 +02:00
|
|
|
unicode_list == NULL && glyph_id_ofs_list == NULL
|
2019-05-20 06:40:00 +02:00
|
|
|
glyph_id = glyph_id_start + rcp
|
|
|
|
|
|
|
|
Format 0 full
|
2019-05-24 06:24:31 +02:00
|
|
|
unicode_list == NULL && glyph_id_ofs_list != NULL
|
|
|
|
glyph_id = glyph_id_start + glyph_id_ofs_list[rcp]
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
Sparse tiny
|
2019-05-24 06:24:31 +02:00
|
|
|
unicode_list != NULL && glyph_id_ofs_list == NULL
|
2019-05-20 06:40:00 +02:00
|
|
|
glyph_id = glyph_id_start + search(unicode_list, rcp)
|
|
|
|
|
|
|
|
Sparse full
|
2019-05-24 06:24:31 +02:00
|
|
|
unicode_list != NULL && glyph_id_ofs_list != NULL
|
|
|
|
glyph_id = glyph_id_start + glyph_id_ofs_list[search(unicode_list, rcp)]
|
2019-05-20 06:40:00 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
uint16_t * unicode_list;
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** if(type == LV_FONT_FMT_TXT_CMAP_FORMAT0_...) it's `uint8_t *`
|
2019-05-28 08:46:43 +02:00
|
|
|
* if(type == LV_FONT_FMT_TXT_CMAP_SPARSE_...) it's `uint16_t *`
|
2019-05-20 06:40:00 +02:00
|
|
|
*/
|
2019-05-24 06:24:31 +02:00
|
|
|
const void * glyph_id_ofs_list;
|
2019-05-28 12:53:19 +02:00
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** Length of `unicode_list` and/or `glyph_id_ofs_list`*/
|
2019-05-28 12:53:19 +02:00
|
|
|
uint16_t list_length;
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** Type of this character map*/
|
2019-05-28 12:53:19 +02:00
|
|
|
lv_font_fmt_txt_cmap_type_t type :2;
|
2019-05-28 08:46:43 +02:00
|
|
|
}lv_font_fmt_txt_cmap_t;
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** A simple mapping of kern values from pairs*/
|
2019-05-20 06:40:00 +02:00
|
|
|
typedef struct {
|
|
|
|
/*To get a kern value of two code points:
|
2019-05-28 08:46:43 +02:00
|
|
|
1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t
|
2019-05-31 05:34:44 +02:00
|
|
|
2 for(i = 0; i < pair_cnt * 2; i+2)
|
2019-05-31 05:21:27 +02:00
|
|
|
if(gylph_ids[i] == glyph_id_left &&
|
|
|
|
gylph_ids[i+1] == glyph_id_right)
|
|
|
|
return values[i / 2];
|
2019-05-20 06:40:00 +02:00
|
|
|
*/
|
2019-05-31 05:21:27 +02:00
|
|
|
const void * glyph_ids;
|
2019-05-31 05:34:44 +02:00
|
|
|
const int8_t * values;
|
2019-05-31 05:21:27 +02:00
|
|
|
uint32_t pair_cnt :24;
|
2019-06-05 12:25:49 +02:00
|
|
|
uint32_t glyph_ids_size :2; /*0: `glyph_ids` is stored as `uint8_t`; 1: as `uint16_t`*/
|
2019-05-28 08:46:43 +02:00
|
|
|
}lv_font_fmt_txt_kern_pair_t;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** More complex but more optimal class based kern value storage*/
|
2019-05-20 06:40:00 +02:00
|
|
|
typedef struct {
|
|
|
|
/*To get a kern value of two code points:
|
2019-05-28 08:46:43 +02:00
|
|
|
1. Get the `glyph_id_left` and `glyph_id_right` from `lv_font_fmt_txt_cmap_t
|
2019-05-20 06:40:00 +02:00
|
|
|
2 Get the class of the left and right glyphs as `left_class` and `right_class`
|
2019-06-01 21:46:05 +02:00
|
|
|
left_class = left_class_mapping[glyph_id_left];
|
|
|
|
right_class = right_class_mapping[glyph_id_right];
|
2019-05-20 06:40:00 +02:00
|
|
|
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
|
|
|
|
*/
|
|
|
|
|
2019-05-29 06:40:19 +02:00
|
|
|
const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/
|
|
|
|
const uint8_t * left_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
|
|
|
const uint8_t * right_class_mapping; /*Map the glyph_ids to classes: index -> glyph_id -> class_id*/
|
2019-05-20 06:40:00 +02:00
|
|
|
uint8_t left_class_cnt;
|
|
|
|
uint8_t right_class_cnt;
|
2019-05-28 08:46:43 +02:00
|
|
|
}lv_font_fmt_txt_kern_classes_t;
|
|
|
|
|
|
|
|
|
2019-06-27 18:07:26 -04:00
|
|
|
/** Bitmap formats*/
|
2019-05-28 08:46:43 +02:00
|
|
|
typedef enum {
|
|
|
|
LV_FONT_FMT_TXT_PLAIN = 0,
|
|
|
|
LV_FONT_FMT_TXT_COMPRESSED = 1,
|
|
|
|
}lv_font_fmt_txt_bitmap_format_t;
|
|
|
|
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/*Describe store additional data for fonts */
|
|
|
|
typedef struct {
|
|
|
|
/*The bitmaps os all glyphs*/
|
|
|
|
const uint8_t * glyph_bitmap;
|
|
|
|
|
|
|
|
/*Describe the glyphs*/
|
2019-05-28 08:46:43 +02:00
|
|
|
const lv_font_fmt_txt_glyph_dsc_t * glyph_dsc;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/* Map the glyphs to Unicode characters.
|
|
|
|
* Array of `lv_font_cmap_fmt_txt_t` variables*/
|
2019-05-28 08:46:43 +02:00
|
|
|
const lv_font_fmt_txt_cmap_t * cmaps;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
2019-05-25 19:32:21 +02:00
|
|
|
/* Store kerning values.
|
2019-05-28 08:46:43 +02:00
|
|
|
* Can be `lv_font_fmt_txt_kern_pair_t * or `lv_font_kern_classes_fmt_txt_t *`
|
2019-05-20 06:40:00 +02:00
|
|
|
* depending on `kern_classes`
|
2019-05-25 19:32:21 +02:00
|
|
|
*/
|
2019-05-20 06:40:00 +02:00
|
|
|
const void * kern_dsc;
|
|
|
|
|
2019-05-25 19:32:21 +02:00
|
|
|
/*Scale kern values in 12.4 format*/
|
|
|
|
uint16_t kern_scale;
|
|
|
|
|
2019-05-20 06:40:00 +02:00
|
|
|
/*Number of cmap tables*/
|
2019-05-25 19:32:21 +02:00
|
|
|
uint16_t cmap_num :10;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/*Bit per pixel: 1, 2, 4 or 8*/
|
|
|
|
uint16_t bpp :3;
|
|
|
|
|
|
|
|
/*Type of `kern_dsc`*/
|
|
|
|
uint16_t kern_classes :1;
|
2019-05-25 19:32:21 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* storage format of the bitmap
|
2019-05-28 08:46:43 +02:00
|
|
|
* from `lv_font_fmt_txt_bitmap_format_t`
|
2019-05-25 19:32:21 +02:00
|
|
|
*/
|
|
|
|
uint16_t bitmap_format :2;
|
2019-06-14 05:55:43 +02:00
|
|
|
|
|
|
|
/*Cache the last letter and is glyph id*/
|
|
|
|
uint32_t last_letter;
|
|
|
|
uint32_t last_glyph_id;
|
|
|
|
|
2019-05-28 08:46:43 +02:00
|
|
|
}lv_font_fmt_txt_dsc_t;
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/**********************
|
|
|
|
* GLOBAL PROTOTYPES
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used as `get_glyph_bitmap` callback in LittelvGL's native font format if the font is uncompressed.
|
|
|
|
* @param font pointer to font
|
|
|
|
* @param unicode_letter an unicode letter which bitmap should be get
|
|
|
|
* @return pointer to the bitmap or NULL if not found
|
|
|
|
*/
|
2019-05-26 19:31:01 +02:00
|
|
|
const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t letter);
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Used as `get_glyph_dsc` callback in LittelvGL's native font format if the font is uncompressed.
|
|
|
|
* @param font_p pointer to font
|
|
|
|
* @param dsc_out store the result descriptor here
|
|
|
|
* @param letter an UNICODE letter code
|
|
|
|
* @return true: descriptor is successfully loaded into `dsc_out`.
|
|
|
|
* false: the letter was not found, no data is loaded to `dsc_out`
|
|
|
|
*/
|
2019-05-29 06:40:19 +02:00
|
|
|
bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t * dsc_out, uint32_t unicode_letter, uint32_t unicode_letter_next);
|
2019-05-20 06:40:00 +02:00
|
|
|
|
|
|
|
/**********************
|
|
|
|
* MACROS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
/**********************
|
|
|
|
* ADD BUILT IN FONTS
|
|
|
|
**********************/
|
|
|
|
|
|
|
|
#ifdef __cplusplus
|
|
|
|
} /* extern "C" */
|
|
|
|
#endif
|
|
|
|
|
2019-05-24 06:24:31 +02:00
|
|
|
#endif /*LV_FONT_FMT_TXT_H*/
|