mirror of
https://github.com/lvgl/lvgl.git
synced 2026-09-28 02:58:42 +08:00
feat(freetype): add outline output to support draw vector font (#4669)
Signed-off-by: FASTSHIFT <vifextech@foxmail.com> Signed-off-by: pengyiqiang <pengyiqiang@xiaomi.com> Co-authored-by: pengyiqiang <pengyiqiang@xiaomi.com>
This commit is contained in:
co-authored by
pengyiqiang
parent
52e6bade58
commit
d06a8d3334
@@ -1125,22 +1125,34 @@ menu "LVGL configuration"
|
||||
config LV_USE_FREETYPE
|
||||
bool "FreeType library"
|
||||
if LV_USE_FREETYPE
|
||||
menu "FreeType cache config"
|
||||
menu "FreeType config"
|
||||
config LV_FREETYPE_CACHE_SIZE
|
||||
int "Memory used by FreeType to cache characters [bytes]"
|
||||
default 65535
|
||||
config LV_FREETYPE_USE_LVGL_PORT
|
||||
bool "Let FreeType to use LVGL memory and file porting"
|
||||
default n
|
||||
config LV_FREETYPE_SBIT_CACHE
|
||||
bool "enable sbit cache"
|
||||
default n
|
||||
config LV_FREETYPE_CACHE_FT_FACES
|
||||
int "The maximum number of FT_Face(0: use defaults)"
|
||||
default 4
|
||||
config LV_FREETYPE_CACHE_FT_SIZES
|
||||
int "The maximum number of FT_Size(0: use defaults)"
|
||||
default 4
|
||||
int "Memory used by FreeType to cache characters in kilobytes"
|
||||
default 768
|
||||
config LV_FREETYPE_USE_LVGL_PORT
|
||||
bool "Let FreeType to use LVGL memory and file porting"
|
||||
default n
|
||||
choice
|
||||
prompt "Freetype cache type"
|
||||
default LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
|
||||
config LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
bool "IMAGE"
|
||||
config LV_FREETYPE_CACHE_TYPE_SBIT
|
||||
bool "SBIT"
|
||||
config LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
bool "OUTLINE"
|
||||
endchoice
|
||||
config LV_FREETYPE_CACHE_FT_FACES
|
||||
int "The maximum number of FT_Face"
|
||||
default 8
|
||||
config LV_FREETYPE_CACHE_FT_SIZES
|
||||
int "The maximum number of FT_Size"
|
||||
default 8
|
||||
config LV_FREETYPE_CACHE_FT_OUTLINES
|
||||
int "The maximum number of Outline"
|
||||
depends on LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
default 256
|
||||
endmenu
|
||||
|
||||
config LV_USE_TINY_TTF
|
||||
|
||||
+10
-8
@@ -634,21 +634,23 @@
|
||||
/*FreeType library*/
|
||||
#define LV_USE_FREETYPE 0
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters [bytes]*/
|
||||
#define LV_FREETYPE_CACHE_SIZE (64 * 1024)
|
||||
/*Memory used by FreeType to cache characters in kilobytes*/
|
||||
#define LV_FREETYPE_CACHE_SIZE 768
|
||||
|
||||
/*Let FreeType to use LVGL memory and file porting*/
|
||||
#define LV_FREETYPE_USE_LVGL_PORT 0
|
||||
|
||||
/* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
|
||||
/* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
|
||||
/* if font size >= 256, must be configured as image cache */
|
||||
#define LV_FREETYPE_SBIT_CACHE 0
|
||||
/*FreeType cache type:
|
||||
* LV_FREETYPE_CACHE_TYPE_IMAGE - Image cache
|
||||
* LV_FREETYPE_CACHE_TYPE_SBIT - Sbit cache
|
||||
* LV_FREETYPE_CACHE_TYPE_OUTLINE - Outline cache*/
|
||||
#define LV_FREETYPE_CACHE_TYPE LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
|
||||
/* Maximum number of opened FT_Face/FT_Size objects managed by this cache instance. */
|
||||
/* (0:use system defaults) */
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 4
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 4
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 8
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 8
|
||||
#define LV_FREETYPE_CACHE_FT_OUTLINES 256
|
||||
#endif
|
||||
|
||||
/* Built-in TTF decoder */
|
||||
|
||||
Regular → Executable
+189
-312
File diff suppressed because it is too large
Load Diff
Regular → Executable
+114
-6
@@ -13,21 +13,63 @@ extern "C" {
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../../../lvgl.h"
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#define LV_FREETYPE_CACHE_TYPE_IMAGE 0
|
||||
#define LV_FREETYPE_CACHE_TYPE_SBIT 1
|
||||
#define LV_FREETYPE_CACHE_TYPE_OUTLINE 2
|
||||
|
||||
#define LV_FREETYPE_F26DOT6_TO_INT(x) ((x) >> 6)
|
||||
#define LV_FREETYPE_F26DOT6_TO_FLOAT(x) ((float)(x) / 64)
|
||||
|
||||
#define FT_FONT_STYLE_NORMAL LV_FREETYPE_FONT_STYLE_NORMAL
|
||||
#define FT_FONT_STYLE_ITALIC LV_FREETYPE_FONT_STYLE_ITALIC
|
||||
#define FT_FONT_STYLE_BOLD LV_FREETYPE_FONT_STYLE_BOLD
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef enum {
|
||||
enum {
|
||||
LV_FREETYPE_FONT_STYLE_NORMAL = 0,
|
||||
LV_FREETYPE_FONT_STYLE_ITALIC = 1 << 0,
|
||||
LV_FREETYPE_FONT_STYLE_BOLD = 1 << 1
|
||||
} lv_freetype_font_style_t;
|
||||
LV_FREETYPE_FONT_STYLE_BOLD = 1 << 1,
|
||||
};
|
||||
|
||||
typedef uint16_t lv_freetype_font_style_t;
|
||||
typedef lv_freetype_font_style_t LV_FT_FONT_STYLE;
|
||||
|
||||
#if LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
|
||||
typedef void * lv_freetype_outline_t;
|
||||
|
||||
typedef enum {
|
||||
LV_FREETYPE_OUTLINE_END,
|
||||
LV_FREETYPE_OUTLINE_MOVE_TO,
|
||||
LV_FREETYPE_OUTLINE_LINE_TO,
|
||||
LV_FREETYPE_OUTLINE_CUBIC_TO,
|
||||
LV_FREETYPE_OUTLINE_CONIC_TO,
|
||||
} lv_freetype_outline_type_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t x;
|
||||
int32_t y;
|
||||
} lv_freetype_outline_vector_t;
|
||||
|
||||
typedef struct {
|
||||
lv_freetype_outline_t outline;
|
||||
lv_freetype_outline_type_t type;
|
||||
lv_freetype_outline_vector_t to;
|
||||
lv_freetype_outline_vector_t control1;
|
||||
lv_freetype_outline_vector_t control2;
|
||||
} lv_freetype_outline_event_param_t;
|
||||
|
||||
#endif /*LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE*/
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
@@ -37,11 +79,11 @@ typedef enum {
|
||||
* Initialize the freetype library.
|
||||
* @param max_faces Maximum number of opened FT_Face objects managed by this cache instance. Use 0 for defaults.
|
||||
* @param max_sizes Maximum number of opened FT_Size objects managed by this cache instance. Use 0 for defaults.
|
||||
* @param max_bytes Maximum number of bytes to use for cached data nodes. Use 0 for defaults.
|
||||
* @param max_kilobytes Maximum number of kilobytes to use for cached data nodes. Use 0 for defaults.
|
||||
* Note that this value does not account for managed FT_Face and FT_Size objects.
|
||||
* @return LV_RESULT_OK on success, otherwise LV_RESULT_INVALID.
|
||||
*/
|
||||
lv_result_t lv_freetype_init(uint16_t max_faces, uint16_t max_sizes, uint32_t max_bytes);
|
||||
lv_result_t lv_freetype_init(uint32_t max_faces, uint32_t max_sizes, uint32_t max_kilobytes);
|
||||
|
||||
/**
|
||||
* Uninitialize the freetype library
|
||||
@@ -55,7 +97,7 @@ void lv_freetype_uninit(void);
|
||||
* @param style font style(see lv_freetype_font_style_t for details).
|
||||
* @return Created font, or NULL on failure.
|
||||
*/
|
||||
lv_font_t * lv_freetype_font_create(const char * pathname, uint16_t size, uint16_t style);
|
||||
lv_font_t * lv_freetype_font_create(const char * pathname, uint32_t size, lv_freetype_font_style_t style);
|
||||
|
||||
/**
|
||||
* Delete a freetype font.
|
||||
@@ -63,6 +105,72 @@ lv_font_t * lv_freetype_font_create(const char * pathname, uint16_t size, uint16
|
||||
*/
|
||||
void lv_freetype_font_delete(lv_font_t * font);
|
||||
|
||||
#if LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
|
||||
/**
|
||||
* Register a callback function to generate outlines for FreeType fonts.
|
||||
*
|
||||
* @param cb The callback function to be registered.
|
||||
* @param user_data User data to be passed to the callback function.
|
||||
* @return The ID of the registered callback function, or a negative value on failure.
|
||||
*/
|
||||
void lv_freetype_outline_add_event(lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
|
||||
|
||||
void lv_freetype_outline_set_ref_size(uint32_t size);
|
||||
|
||||
uint32_t lv_freetype_outline_get_ref_size(void);
|
||||
|
||||
/**
|
||||
* Get the scale of a FreeType font.
|
||||
*
|
||||
* @param font The FreeType font to get the scale of.
|
||||
* @return The scale of the FreeType font.
|
||||
*/
|
||||
uint32_t lv_freetype_outline_get_scale(const lv_font_t * font);
|
||||
|
||||
/**
|
||||
* Check if the font is an outline font.
|
||||
*
|
||||
* @param font The FreeType font.
|
||||
* @return Is outline font on success, otherwise false.
|
||||
*/
|
||||
bool lv_freetype_is_outline_font(const lv_font_t * font);
|
||||
|
||||
#endif
|
||||
|
||||
#if LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
|
||||
/**
|
||||
* Register a callback function to generate outlines for FreeType fonts.
|
||||
*
|
||||
* @param cb The callback function to be registered.
|
||||
* @param user_data User data to be passed to the callback function.
|
||||
* @return The ID of the registered callback function, or a negative value on failure.
|
||||
*/
|
||||
void lv_freetype_outline_add_event(lv_event_cb_t event_cb, lv_event_code_t filter, void * user_data);
|
||||
|
||||
void lv_freetype_outline_set_ref_size(uint32_t size);
|
||||
|
||||
uint32_t lv_freetype_outline_get_ref_size(void);
|
||||
|
||||
/**
|
||||
* Get the scale of a FreeType font.
|
||||
*
|
||||
* @param font The FreeType font to get the scale of.
|
||||
* @return The scale of the FreeType font.
|
||||
*/
|
||||
uint32_t lv_freetype_outline_get_scale(const lv_font_t * font);
|
||||
|
||||
/**
|
||||
* Check if the font is an outline font.
|
||||
*
|
||||
* @param font The FreeType font.
|
||||
* @return Is outline font on success, otherwise false.
|
||||
*/
|
||||
bool lv_freetype_is_outline_font(const lv_font_t * font);
|
||||
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
Executable
+183
@@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @file lv_freetype_image.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_freetype_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_FREETYPE && LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_freetype_cache_context_t {
|
||||
FTC_ImageCache image_cache;
|
||||
};
|
||||
|
||||
struct _lv_freetype_cache_node_t {
|
||||
FT_Glyph image_glyph;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static bool freetype_get_glyph_dsc_cb(const lv_font_t * font,
|
||||
lv_font_glyph_dsc_t * dsc_out,
|
||||
uint32_t unicode_letter,
|
||||
uint32_t unicode_letter_next);
|
||||
|
||||
static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter,
|
||||
uint8_t * bitmap_out);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_freetype_cache_context_t * lv_freetype_cache_context_create(lv_freetype_context_t * ctx)
|
||||
{
|
||||
lv_freetype_cache_context_t * cache_ctx = lv_malloc(sizeof(lv_freetype_cache_context_t));
|
||||
LV_ASSERT_MALLOC(cache_ctx);
|
||||
lv_memzero(cache_ctx, sizeof(lv_freetype_cache_context_t));
|
||||
|
||||
FT_Error error = FTC_ImageCache_New(ctx->cache_manager, &cache_ctx->image_cache);
|
||||
if(error) {
|
||||
FT_ERROR_MSG("FTC_ImageCache_New", error);
|
||||
lv_free(cache_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cache_ctx;
|
||||
}
|
||||
|
||||
void lv_freetype_cache_context_delete(lv_freetype_cache_context_t * cache_ctx)
|
||||
{
|
||||
LV_ASSERT_NULL(cache_ctx);
|
||||
lv_free(cache_ctx);
|
||||
}
|
||||
|
||||
bool lv_freetype_on_font_create(lv_freetype_font_dsc_t * dsc)
|
||||
{
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
lv_freetype_cache_node_t * cache_node = lv_malloc(sizeof(lv_freetype_cache_node_t));
|
||||
LV_ASSERT_MALLOC(cache_node);
|
||||
lv_memzero(cache_node, sizeof(lv_freetype_cache_context_t));
|
||||
dsc->cache_node = cache_node;
|
||||
dsc->font.get_glyph_dsc = freetype_get_glyph_dsc_cb;
|
||||
dsc->font.get_glyph_bitmap = freetype_get_glyph_bitmap_cb;
|
||||
return true;
|
||||
}
|
||||
|
||||
void lv_freetype_on_font_delete(lv_freetype_font_dsc_t * dsc)
|
||||
{
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
LV_ASSERT_NULL(dsc->cache_node);
|
||||
lv_free(dsc->cache_node);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool freetype_get_glyph_dsc_cb(const lv_font_t * font,
|
||||
lv_font_glyph_dsc_t * dsc_out,
|
||||
uint32_t unicode_letter,
|
||||
uint32_t unicode_letter_next)
|
||||
{
|
||||
if(unicode_letter < 0x20) {
|
||||
dsc_out->adv_w = 0;
|
||||
dsc_out->box_h = 0;
|
||||
dsc_out->box_w = 0;
|
||||
dsc_out->ofs_x = 0;
|
||||
dsc_out->ofs_y = 0;
|
||||
dsc_out->bpp = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
|
||||
FT_Error error;
|
||||
|
||||
FT_Size ft_size = lv_freetype_lookup_size(dsc);
|
||||
if(!ft_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Face face = ft_size->face;
|
||||
FT_UInt charmap_index = FT_Get_Charmap_Index(face->charmap);
|
||||
FT_UInt glyph_index = FTC_CMapCache_Lookup(dsc->context->cmap_cache, dsc->face_id, charmap_index, unicode_letter);
|
||||
dsc_out->is_placeholder = glyph_index == 0;
|
||||
|
||||
if(dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) {
|
||||
lv_freetype_italic_transform(face);
|
||||
}
|
||||
|
||||
FTC_ImageTypeRec desc_type;
|
||||
desc_type.face_id = dsc->face_id;
|
||||
desc_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
|
||||
desc_type.height = dsc->size;
|
||||
desc_type.width = dsc->size;
|
||||
|
||||
error = FTC_ImageCache_Lookup(dsc->context->cache_context->image_cache,
|
||||
&desc_type,
|
||||
glyph_index,
|
||||
&dsc->cache_node->image_glyph,
|
||||
NULL);
|
||||
if(error) {
|
||||
FT_ERROR_MSG("ImageCache_Lookup", error);
|
||||
return false;
|
||||
}
|
||||
if(dsc->cache_node->image_glyph->format != FT_GLYPH_FORMAT_BITMAP) {
|
||||
LV_LOG_WARN("glyph format(%d) != FT_GLYPH_FORMAT_BITMAP", dsc->cache_node->image_glyph->format);
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)dsc->cache_node->image_glyph;
|
||||
|
||||
dsc_out->adv_w = FT_F16DOT16_TO_INT(glyph_bitmap->root.advance.x);
|
||||
dsc_out->box_h = glyph_bitmap->bitmap.rows; /*Height of the bitmap in [px]*/
|
||||
dsc_out->box_w = glyph_bitmap->bitmap.width; /*Width of the bitmap in [px]*/
|
||||
dsc_out->ofs_x = glyph_bitmap->left; /*X offset of the bitmap in [pf]*/
|
||||
dsc_out->ofs_y = glyph_bitmap->top -
|
||||
glyph_bitmap->bitmap.rows; /*Y offset of the bitmap measured from the as line*/
|
||||
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
|
||||
|
||||
if((dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) {
|
||||
dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter,
|
||||
uint8_t * bitmap_out)
|
||||
{
|
||||
LV_UNUSED(unicode_letter);
|
||||
LV_UNUSED(bitmap_out);
|
||||
|
||||
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
|
||||
FT_BitmapGlyph glyph_bitmap = (FT_BitmapGlyph)dsc->cache_node->image_glyph;
|
||||
return (const uint8_t *)glyph_bitmap->bitmap.buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
Executable
+637
File diff suppressed because it is too large
Load Diff
Executable
+126
@@ -0,0 +1,126 @@
|
||||
/**
|
||||
* @file lv_freetype_private.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_FREETYPE_PRIVATE_H
|
||||
#define LV_FREETYPE_PRIVATE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "../../../lvgl.h"
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
|
||||
#include "ft2build.h"
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_GLYPH_H
|
||||
#include FT_CACHE_H
|
||||
#include FT_SIZES_H
|
||||
#include FT_IMAGE_H
|
||||
#include FT_OUTLINE_H
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#ifdef FT_CONFIG_OPTION_ERROR_STRINGS
|
||||
#define FT_ERROR_MSG(msg, error_code) \
|
||||
LV_LOG_ERROR(msg " error(0x%x): %s", (int)error_code, FT_Error_String(error_code))
|
||||
#else
|
||||
#define FT_ERROR_MSG(msg, error_code) \
|
||||
LV_LOG_ERROR(msg " error(0x%x)", (int)error_code)
|
||||
#endif
|
||||
|
||||
#if LV_FREETYPE_CACHE_SIZE <= 0
|
||||
#error "LV_FREETYPE_CACHE_SIZE must > 0"
|
||||
#endif
|
||||
|
||||
#define LV_FREETYPE_FONT_DSC_MAGIC_NUM 0x5F5F4654 /* '__FT' */
|
||||
#define LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc) ((dsc)->magic_num == LV_FREETYPE_FONT_DSC_MAGIC_NUM)
|
||||
#define LV_ASSERT_FREETYPE_FONT_DSC(dsc) \
|
||||
do { \
|
||||
LV_ASSERT_NULL(dsc); \
|
||||
LV_ASSERT_MSG(LV_FREETYPE_FONT_DSC_HAS_MAGIC_NUM(dsc), "Invalid font descriptor"); \
|
||||
} while (0)
|
||||
|
||||
#define FT_INT_TO_F26DOT6(x) ((x) << 6)
|
||||
#define FT_F26DOT6_TO_INT(x) ((x) >> 6)
|
||||
|
||||
#define FT_INT_TO_F16DOT16(x) ((x) << 16)
|
||||
#define FT_F16DOT16_TO_INT(x) ((x) >> 16)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct _lv_freetype_cache_context_t lv_freetype_cache_context_t;
|
||||
typedef struct _lv_freetype_cache_node_t lv_freetype_cache_node_t;
|
||||
|
||||
typedef struct _lv_freetype_context_t {
|
||||
FT_Library library;
|
||||
FTC_Manager cache_manager;
|
||||
FTC_CMapCache cmap_cache;
|
||||
lv_freetype_cache_context_t * cache_context;
|
||||
lv_ll_t face_id_ll;
|
||||
} lv_freetype_context_t;
|
||||
|
||||
typedef struct _lv_freetype_font_dsc_t {
|
||||
uint32_t magic_num;
|
||||
lv_font_t font;
|
||||
uint32_t size;
|
||||
lv_freetype_font_style_t style;
|
||||
lv_freetype_context_t * context;
|
||||
lv_freetype_cache_node_t * cache_node;
|
||||
FTC_FaceID face_id;
|
||||
} lv_freetype_font_dsc_t;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Get the FreeType context.
|
||||
*
|
||||
* @return A pointer to the FreeType context used by LittlevGL.
|
||||
*/
|
||||
lv_freetype_context_t * lv_freetype_get_context(void);
|
||||
|
||||
/**
|
||||
* Look up a FreeType size object for a given font descriptor and size.
|
||||
*
|
||||
* @param dsc The font descriptor to use.
|
||||
* @param size The size of the font.
|
||||
* @return A pointer to the FreeType size object.
|
||||
*/
|
||||
FT_Size lv_freetype_lookup_size(const lv_freetype_font_dsc_t * dsc);
|
||||
|
||||
lv_freetype_cache_context_t * lv_freetype_cache_context_create(lv_freetype_context_t * ctx);
|
||||
|
||||
void lv_freetype_cache_context_delete(lv_freetype_cache_context_t * cache_ctx);
|
||||
|
||||
bool lv_freetype_on_font_create(lv_freetype_font_dsc_t * dsc);
|
||||
|
||||
void lv_freetype_on_font_delete(lv_freetype_font_dsc_t * dsc);
|
||||
|
||||
void lv_freetype_italic_transform(FT_Face face);
|
||||
|
||||
const char * lv_freetype_get_pathname(FTC_FaceID face_id);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /*LV_USE_FREETYPE*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_FREETYPE_PRIVATE_H*/
|
||||
Executable
+178
@@ -0,0 +1,178 @@
|
||||
/**
|
||||
* @file lv_freetype_sbit.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include "lv_freetype_private.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
#if LV_USE_FREETYPE && LV_FREETYPE_CACHE_TYPE == LV_FREETYPE_CACHE_TYPE_SBIT
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
struct _lv_freetype_cache_context_t {
|
||||
FTC_SBitCache sbit_cache;
|
||||
};
|
||||
|
||||
struct _lv_freetype_cache_node_t {
|
||||
FTC_SBit sbit;
|
||||
};
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static bool freetype_get_glyph_dsc_cb(const lv_font_t * font,
|
||||
lv_font_glyph_dsc_t * dsc_out,
|
||||
uint32_t unicode_letter,
|
||||
uint32_t unicode_letter_next);
|
||||
|
||||
static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter,
|
||||
uint8_t * bitmap_out);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_freetype_cache_context_t * lv_freetype_cache_context_create(lv_freetype_context_t * ctx)
|
||||
{
|
||||
LV_UNUSED(ctx);
|
||||
lv_freetype_cache_context_t * cache_ctx = lv_malloc(sizeof(lv_freetype_cache_context_t));
|
||||
LV_ASSERT_MALLOC(cache_ctx);
|
||||
lv_memzero(cache_ctx, sizeof(lv_freetype_cache_context_t));
|
||||
|
||||
FT_Error error = FTC_SBitCache_New(ctx->cache_manager, &cache_ctx->sbit_cache);
|
||||
if(error) {
|
||||
FT_ERROR_MSG("FTC_SBitCache_New", error);
|
||||
lv_free(cache_ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return cache_ctx;
|
||||
}
|
||||
|
||||
void lv_freetype_cache_context_delete(lv_freetype_cache_context_t * cache_ctx)
|
||||
{
|
||||
LV_ASSERT_NULL(cache_ctx);
|
||||
lv_free(cache_ctx);
|
||||
}
|
||||
|
||||
bool lv_freetype_on_font_create(lv_freetype_font_dsc_t * dsc)
|
||||
{
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
lv_freetype_cache_node_t * cache_node = lv_malloc(sizeof(lv_freetype_cache_node_t));
|
||||
LV_ASSERT_MALLOC(cache_node);
|
||||
lv_memzero(cache_node, sizeof(lv_freetype_cache_context_t));
|
||||
dsc->cache_node = cache_node;
|
||||
dsc->font.get_glyph_dsc = freetype_get_glyph_dsc_cb;
|
||||
dsc->font.get_glyph_bitmap = freetype_get_glyph_bitmap_cb;
|
||||
return true;
|
||||
}
|
||||
|
||||
void lv_freetype_on_font_delete(lv_freetype_font_dsc_t * dsc)
|
||||
{
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
LV_ASSERT_NULL(dsc->cache_node);
|
||||
lv_free(dsc->cache_node);
|
||||
dsc->cache_node = NULL;
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static bool freetype_get_glyph_dsc_cb(const lv_font_t * font,
|
||||
lv_font_glyph_dsc_t * dsc_out,
|
||||
uint32_t unicode_letter,
|
||||
uint32_t unicode_letter_next)
|
||||
{
|
||||
if(unicode_letter < 0x20) {
|
||||
dsc_out->adv_w = 0;
|
||||
dsc_out->box_h = 0;
|
||||
dsc_out->box_w = 0;
|
||||
dsc_out->ofs_x = 0;
|
||||
dsc_out->ofs_y = 0;
|
||||
dsc_out->bpp = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
|
||||
FT_Error error;
|
||||
|
||||
FT_Size ft_size = lv_freetype_lookup_size(dsc);
|
||||
if(!ft_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FT_Face face = ft_size->face;
|
||||
FT_UInt charmap_index = FT_Get_Charmap_Index(face->charmap);
|
||||
FT_UInt glyph_index = FTC_CMapCache_Lookup(dsc->context->cmap_cache, dsc->face_id, charmap_index, unicode_letter);
|
||||
dsc_out->is_placeholder = glyph_index == 0;
|
||||
|
||||
if(dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) {
|
||||
lv_freetype_italic_transform(face);
|
||||
}
|
||||
|
||||
FTC_ImageTypeRec desc_type;
|
||||
desc_type.face_id = dsc->face_id;
|
||||
desc_type.flags = FT_LOAD_RENDER | FT_LOAD_TARGET_NORMAL;
|
||||
desc_type.height = dsc->size;
|
||||
desc_type.width = dsc->size;
|
||||
|
||||
error = FTC_SBitCache_Lookup(dsc->context->cache_context->sbit_cache,
|
||||
&desc_type,
|
||||
glyph_index,
|
||||
&dsc->cache_node->sbit,
|
||||
NULL);
|
||||
if(error) {
|
||||
FT_ERROR_MSG("FTC_SBitCache_Lookup", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
FTC_SBit sbit = dsc->cache_node->sbit;
|
||||
dsc_out->adv_w = sbit->xadvance;
|
||||
dsc_out->box_h = sbit->height; /*Height of the bitmap in [px]*/
|
||||
dsc_out->box_w = sbit->width; /*Width of the bitmap in [px]*/
|
||||
dsc_out->ofs_x = sbit->left; /*X offset of the bitmap in [pf]*/
|
||||
dsc_out->ofs_y = sbit->top - sbit->height; /*Y offset of the bitmap measured from the as line*/
|
||||
dsc_out->bpp = 8; /*Bit per pixel: 1/2/4/8*/
|
||||
|
||||
if((dsc->style & LV_FREETYPE_FONT_STYLE_ITALIC) && (unicode_letter_next == '\0')) {
|
||||
dsc_out->adv_w = dsc_out->box_w + dsc_out->ofs_x;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static const uint8_t * freetype_get_glyph_bitmap_cb(const lv_font_t * font, uint32_t unicode_letter,
|
||||
uint8_t * bitmap_out)
|
||||
{
|
||||
LV_UNUSED(unicode_letter);
|
||||
LV_UNUSED(bitmap_out);
|
||||
|
||||
lv_freetype_font_dsc_t * dsc = (lv_freetype_font_dsc_t *)font->dsc;
|
||||
LV_ASSERT_FREETYPE_FONT_DSC(dsc);
|
||||
|
||||
return (const uint8_t *)dsc->cache_node->sbit->buffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
+19
-11
@@ -2100,12 +2100,12 @@
|
||||
#endif
|
||||
#endif
|
||||
#if LV_USE_FREETYPE
|
||||
/*Memory used by FreeType to cache characters [bytes]*/
|
||||
/*Memory used by FreeType to cache characters in kilobytes*/
|
||||
#ifndef LV_FREETYPE_CACHE_SIZE
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_SIZE
|
||||
#define LV_FREETYPE_CACHE_SIZE CONFIG_LV_FREETYPE_CACHE_SIZE
|
||||
#else
|
||||
#define LV_FREETYPE_CACHE_SIZE (64 * 1024)
|
||||
#define LV_FREETYPE_CACHE_SIZE 768
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2118,14 +2118,15 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* 1: bitmap cache use the sbit cache, 0:bitmap cache use the image cache. */
|
||||
/* sbit cache:it is much more memory efficient for small bitmaps(font size < 256) */
|
||||
/* if font size >= 256, must be configured as image cache */
|
||||
#ifndef LV_FREETYPE_SBIT_CACHE
|
||||
#ifdef CONFIG_LV_FREETYPE_SBIT_CACHE
|
||||
#define LV_FREETYPE_SBIT_CACHE CONFIG_LV_FREETYPE_SBIT_CACHE
|
||||
/*FreeType cache type:
|
||||
* LV_FREETYPE_CACHE_TYPE_IMAGE - Image cache
|
||||
* LV_FREETYPE_CACHE_TYPE_SBIT - Sbit cache
|
||||
* LV_FREETYPE_CACHE_TYPE_OUTLINE - Outline cache*/
|
||||
#ifndef LV_FREETYPE_CACHE_TYPE
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_TYPE
|
||||
#define LV_FREETYPE_CACHE_TYPE CONFIG_LV_FREETYPE_CACHE_TYPE
|
||||
#else
|
||||
#define LV_FREETYPE_SBIT_CACHE 0
|
||||
#define LV_FREETYPE_CACHE_TYPE LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2135,14 +2136,21 @@
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_FT_FACES
|
||||
#define LV_FREETYPE_CACHE_FT_FACES CONFIG_LV_FREETYPE_CACHE_FT_FACES
|
||||
#else
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 4
|
||||
#define LV_FREETYPE_CACHE_FT_FACES 8
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_FREETYPE_CACHE_FT_SIZES
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_FT_SIZES
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES CONFIG_LV_FREETYPE_CACHE_FT_SIZES
|
||||
#else
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 4
|
||||
#define LV_FREETYPE_CACHE_FT_SIZES 8
|
||||
#endif
|
||||
#endif
|
||||
#ifndef LV_FREETYPE_CACHE_FT_OUTLINES
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_FT_OUTLINES
|
||||
#define LV_FREETYPE_CACHE_FT_OUTLINES CONFIG_LV_FREETYPE_CACHE_FT_OUTLINES
|
||||
#else
|
||||
#define LV_FREETYPE_CACHE_FT_OUTLINES 256
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -235,6 +235,18 @@ extern "C" {
|
||||
# define CONFIG_LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_FULL
|
||||
#endif
|
||||
|
||||
/*------------------
|
||||
* FREETYPE
|
||||
*-----------------*/
|
||||
|
||||
#ifdef CONFIG_LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
# define CONFIG_LV_FREETYPE_CACHE_TYPE LV_FREETYPE_CACHE_TYPE_IMAGE
|
||||
#elif defined(CONFIG_LV_FREETYPE_CACHE_TYPE_SBIT)
|
||||
# define CONFIG_LV_FREETYPE_CACHE_TYPE LV_FREETYPE_CACHE_TYPE_SBIT
|
||||
#elif defined(CONFIG_LV_FREETYPE_CACHE_TYPE_OUTLINE)
|
||||
# define CONFIG_LV_FREETYPE_CACHE_TYPE LV_FREETYPE_CACHE_TYPE_OUTLINE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
@@ -81,6 +81,7 @@ typedef enum {
|
||||
LV_EVENT_CANCEL, /**< A process has been cancelled */
|
||||
|
||||
/** Other events*/
|
||||
LV_EVENT_CREATE, /**< Object is being created*/
|
||||
LV_EVENT_DELETE, /**< Object is being deleted*/
|
||||
LV_EVENT_CHILD_CHANGED, /**< Child was removed, added, or its size, position were changed */
|
||||
LV_EVENT_CHILD_CREATED, /**< Child was created, always bubbles up to all parents*/
|
||||
|
||||
Regular → Executable
Regular → Executable
+1
-7
@@ -42,13 +42,7 @@ typedef void (*lv_lru_free_cb_t)(void * v);
|
||||
|
||||
typedef struct _lv_lru_item_t lv_lru_item_t;
|
||||
|
||||
typedef struct /// @cond
|
||||
/**
|
||||
* Tells Doxygen to ignore a duplicate declaration
|
||||
*/
|
||||
lv_lru_t
|
||||
/// @endcond
|
||||
{
|
||||
typedef struct lv_lru_t {
|
||||
lv_lru_item_t ** items;
|
||||
uint64_t access_count;
|
||||
size_t free_memory;
|
||||
|
||||
Regular → Executable
Regular → Executable
Regular → Executable
Regular → Executable
Reference in New Issue
Block a user