add subpx rendering

This commit is contained in:
Gabor Kiss-Vamosi
2019-10-16 14:42:15 +02:00
20 changed files with 1254 additions and 1625 deletions

View File

@@ -93,7 +93,7 @@ You can use the [Simulators](https://docs.littlevgl.com/en/html/get-started/pc-s
1. [Download](https://littlevgl.com/download) or [Clone](https://github.com/littlevgl/lvgl) the library
2. Copy the `lvgl` folder into your project
3. Copy `lvgl/lv_conf_templ.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
3. Copy `lvgl/lv_conf_template.h` as `lv_conf.h` next to the `lvgl` folder and set at least `LV_HOR_RES_MAX`, `LV_VER_RES_MAX` and `LV_COLOR_DEPTH`.
4. Include `lvgl/lvgl.h` where you need to use LittlevGL related functions.
5. Call `lv_tick_inc(x)` every `x` milliseconds **in a Timer or Task** (`x` should be between 1 and 10). It is required for the internal timing of LittlevGL.
6. Call `lv_init()`

View File

@@ -353,6 +353,12 @@ typedef void * lv_font_user_data_t;
# define lv_vsnprintf vsnprintf
#endif /*LV_SPRINTF_CUSTOM*/
/* Set the pixel order of the display.
* Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter.
*/
#define LV_SUBPX_BGR 0
/*===================
* LV_OBJ SETTINGS
*==================*/

View File

@@ -496,6 +496,14 @@
#endif
#endif /*LV_SPRINTF_CUSTOM*/
/* Set the pixel order of the display.
* Important only if "subpx fonts" are used.
* With "normal" font it doesn't matter.
*/
#ifndef LV_SUBPX_BGR
#define LV_SUBPX_BGR 0
#endif
/*===================
* LV_OBJ SETTINGS
*==================*/

View File

@@ -4,6 +4,7 @@ CSRCS += lv_disp.c
CSRCS += lv_obj.c
CSRCS += lv_refr.c
CSRCS += lv_style.c
CSRCS += lv_debug.c
DEPPATH += --dep-path $(LVGL_DIR)/lvgl/src/lv_core
VPATH += :$(LVGL_DIR)/lvgl/src/lv_core

View File

@@ -17,7 +17,6 @@
#define LABEL_RECOLOR_PAR_LENGTH 6
#define LV_LABEL_HINT_UPDATE_TH 1024 /*Update the "hint" if the label's y coordinates have changed more then this*/
/**********************
* TYPEDEFS
**********************/
@@ -33,12 +32,23 @@ typedef uint8_t cmd_state_t;
**********************/
static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa);
static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, const uint8_t * map_p, lv_color_t color, lv_opa_t opa);
static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, const uint8_t * map_p, lv_color_t color, lv_opa_t opa);
static uint8_t hex_char_to_num(char hex);
/**********************
* STATIC VARIABLES
**********************/
/*clang-format off*/
static const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
static const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
static const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
68, 85, 102, 119,
136, 153, 170, 187,
204, 221, 238, 255};
/*clang-format on*/
/**********************
* MACROS
@@ -280,13 +290,6 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, const lv_st
static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area, const lv_font_t * font_p, uint32_t letter,
lv_color_t color, lv_opa_t opa)
{
/*clang-format off*/
const uint8_t bpp1_opa_table[2] = {0, 255}; /*Opacity mapping with bpp = 1 (Just for compatibility)*/
const uint8_t bpp2_opa_table[4] = {0, 85, 170, 255}; /*Opacity mapping with bpp = 2*/
const uint8_t bpp4_opa_table[16] = {0, 17, 34, 51, /*Opacity mapping with bpp = 4*/
68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
/*clang-format on*/
if(opa < LV_OPA_MIN) return;
if(opa > LV_OPA_MAX) opa = LV_OPA_COVER;
@@ -309,13 +312,33 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
lv_coord_t pos_x = pos_p->x + g.ofs_x;
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
/*If the letter is completely out of mask don't draw it */
if(pos_x + g.box_w < clip_area->x1 ||
pos_x > clip_area->x2 ||
pos_y + g.box_h < clip_area->y1 ||
pos_y > clip_area->y2) return;
const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);
if(map_p == NULL) {
LV_LOG_WARN("lv_draw_letter: character's bitmap not found");
return;
}
// draw_letter_normal(pos_x, pos_y, &g, clip_area, map_p, color, opa);
draw_letter_subpx(pos_x, pos_y, &g, clip_area, map_p, color, opa);
}
static void draw_letter_normal(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, const uint8_t * map_p, lv_color_t color, lv_opa_t opa)
{
const uint8_t * bpp_opa_table;
uint8_t bitmask_init;
uint8_t bitmask;
if(g.bpp == 3) g.bpp = 4;
if(g->bpp == 3) g->bpp = 4;
switch(g.bpp) {
switch(g->bpp) {
case 1:
bpp_opa_table = bpp1_opa_table;
bitmask_init = 0x80;
@@ -337,32 +360,23 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
return; /*Invalid bpp. Can't render the letter*/
}
const uint8_t * map_p = lv_font_get_glyph_bitmap(font_p, letter);
if(map_p == NULL) {
LV_LOG_WARN("lv_draw_letter: character's bitmap not found");
return;
}
/*If the letter is completely out of mask don't draw it */
if(pos_x + g.box_w < clip_area->x1 ||
pos_x > clip_area->x2 ||
pos_y + g.box_h < clip_area->y1 ||
pos_y > clip_area->y2) return;
lv_coord_t col, row;
uint8_t width_byte_scr = g.box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(g.box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
uint8_t width_byte_scr = g->box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(g->box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g->box_w * g->bpp; /*Letter width in bits*/
/* Calculate the col/row start/end on the map*/
lv_coord_t col_start = pos_x >= clip_area->x1 ? 0 : clip_area->x1 - pos_x;
lv_coord_t col_end = pos_x + g.box_w <= clip_area->x2 ? g.box_w : clip_area->x2 - pos_x + 1;
lv_coord_t col_end = pos_x + g->box_w <= clip_area->x2 ? g->box_w : clip_area->x2 - pos_x + 1;
lv_coord_t row_start = pos_y >= clip_area->y1 ? 0 : clip_area->y1 - pos_y;
lv_coord_t row_end = pos_y + g.box_h <= clip_area->y2 ? g.box_h : clip_area->y2 - pos_y + 1;
lv_coord_t row_end = pos_y + g->box_h <= clip_area->y2 ? g->box_h : clip_area->y2 - pos_y + 1;
/*Move on the map too*/
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g.bpp);
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g->bpp);
map_p += bit_ofs >> 3;
uint8_t letter_px;
@@ -370,7 +384,7 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
uint16_t col_bit;
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
uint32_t mask_buf_size = g.box_w * g.box_h > LV_HOR_RES_MAX ? g.box_w * g.box_h : LV_HOR_RES_MAX;
uint32_t mask_buf_size = g->box_w * g->box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
lv_opa_t * mask_buf = lv_draw_buf_get(mask_buf_size);
lv_coord_t mask_p = 0;
lv_coord_t mask_p_start;
@@ -389,12 +403,12 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
for(col = col_start; col < col_end; col++) {
/*Load the pixel's opacity into the mask*/
letter_px = (*map_p & bitmask) >> (8 - col_bit - g.bpp);
letter_px = (*map_p & bitmask) >> (8 - col_bit - g->bpp);
if(letter_px != 0) {
if(opa == LV_OPA_COVER) {
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
px_opa = g->bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
px_opa = g->bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
}
@@ -405,9 +419,9 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
}
/*Go to the next column*/
if(col_bit < 8 - g.bpp) {
col_bit += g.bpp;
bitmask = bitmask >> g.bpp;
if(col_bit < 8 - g->bpp) {
col_bit += g->bpp;
bitmask = bitmask >> g->bpp;
} else {
col_bit = 0;
bitmask = bitmask_init;
@@ -438,7 +452,7 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
mask_p = 0;
}
col_bit += ((g.box_w - col_end) + col_start) * g.bpp;
col_bit += ((g->box_w - col_end) + col_start) * g->bpp;
map_p += (col_bit >> 3);
col_bit = col_bit & 0x7;
@@ -456,6 +470,181 @@ static void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * clip_area
lv_draw_buf_release(mask_buf);
}
static void draw_letter_subpx(lv_coord_t pos_x, lv_coord_t pos_y, lv_font_glyph_dsc_t * g, const lv_area_t * clip_area, const uint8_t * map_p, lv_color_t color, lv_opa_t opa)
{
const uint8_t * bpp_opa_table;
uint8_t bitmask_init;
uint8_t bitmask;
if(g->bpp == 3) g->bpp = 4;
switch(g->bpp) {
case 1:
bpp_opa_table = bpp1_opa_table;
bitmask_init = 0x80;
break;
case 2:
bpp_opa_table = bpp2_opa_table;
bitmask_init = 0xC0;
break;
case 4:
bpp_opa_table = bpp4_opa_table;
bitmask_init = 0xF0;
break;
case 8:
bpp_opa_table = NULL;
bitmask_init = 0xFF;
break; /*No opa table, pixel value will be used directly*/
default:
LV_LOG_WARN("lv_draw_letter: invalid bpp not found");
return; /*Invalid bpp. Can't render the letter*/
}
lv_coord_t col, row;
uint8_t width_byte_scr = g->box_w >> 3; /*Width in bytes (on the screen finally) (e.g. w = 11 -> 2 bytes wide)*/
if(g->box_w & 0x7) width_byte_scr++;
uint16_t width_bit = g->box_w * g->bpp; /*Letter width in bits*/
/* Calculate the col/row start/end on the map*/
lv_coord_t col_start = pos_x >= clip_area->x1 ? 0 : (clip_area->x1 - pos_x) * 3;
lv_coord_t col_end = pos_x + g->box_w / 3 <= clip_area->x2 ? g->box_w : (clip_area->x2 - pos_x + 1) * 3;
lv_coord_t row_start = pos_y >= clip_area->y1 ? 0 : clip_area->y1 - pos_y;
lv_coord_t row_end = pos_y + g->box_h <= clip_area->y2 ? g->box_h : clip_area->y2 - pos_y + 1;
/*Move on the map too*/
uint32_t bit_ofs = (row_start * width_bit) + (col_start * g->bpp);
map_p += bit_ofs >> 3;
uint8_t letter_px;
lv_opa_t px_opa;
uint16_t col_bit;
col_bit = bit_ofs & 0x7; /* "& 0x7" equals to "% 8" just faster */
uint32_t mask_buf_size = g->box_w * g->box_h > LV_HOR_RES_MAX ? g->box_w * g->box_h : LV_HOR_RES_MAX;
lv_opa_t * mask_buf = lv_draw_buf_get(mask_buf_size);
lv_coord_t mask_p = 0;
lv_coord_t mask_p_start;
lv_color_t * color_buf = lv_draw_buf_get(mask_buf_size * sizeof(lv_color_t));
lv_disp_t * disp = lv_refr_get_disp_refreshing();
lv_disp_buf_t * vdb = lv_disp_get_buf(disp);
lv_coord_t vdb_width = lv_area_get_width(&vdb->area);
lv_color_t * vdb_buf_tmp = vdb->buf_act;
/*Set a pointer on VDB to the first pixel of the letter*/
vdb_buf_tmp += ((pos_y - vdb->area.y1) * vdb_width) + pos_x - vdb->area.x1;
/*If the letter is partially out of mask the move there on VDB*/
vdb_buf_tmp += (row_start * vdb_width) + col_start / 3;
lv_area_t map_area;
map_area.x1 = col_start / 3 + pos_x;
map_area.x2 = col_end / 3 + pos_x - 1;
map_area.y1 = row_start + pos_y;
map_area.y2 = map_area.y1;
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
uint8_t font_rgb[3];
uint8_t txt_rgb[3] = {color.ch.red, color.ch.green, color.ch.blue};
for(row = row_start ; row < row_end; row++) {
uint8_t subpx_cnt = 0;
bitmask = bitmask_init >> col_bit;
mask_p_start = mask_p;
for(col = col_start; col < col_end; col++) {
/*Load the pixel's opacity into the mask*/
letter_px = (*map_p & bitmask) >> (8 - col_bit - g->bpp);
if(letter_px != 0) {
if(opa == LV_OPA_COVER) {
px_opa = g->bpp == 8 ? letter_px : bpp_opa_table[letter_px];
} else {
px_opa = g->bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
}
} else {
px_opa = 0;
}
font_rgb[subpx_cnt] = px_opa;
subpx_cnt ++;
if(subpx_cnt == 3) {
subpx_cnt = 0;
lv_color_t res_color;
uint8_t bg_rgb[3] = {vdb_buf_tmp->ch.red, vdb_buf_tmp->ch.green, vdb_buf_tmp->ch.blue};
#if LV_SUBPX_BGR
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
#else
res_color.ch.red = (uint16_t)((uint16_t)txt_rgb[0] * font_rgb[0] + (bg_rgb[0] * (255 - font_rgb[0]))) >> 8;
res_color.ch.green = (uint16_t)((uint16_t)txt_rgb[1] * font_rgb[1] + (bg_rgb[1] * (255 - font_rgb[1]))) >> 8;
res_color.ch.blue = (uint16_t)((uint16_t)txt_rgb[2] * font_rgb[2] + (bg_rgb[2] * (255 - font_rgb[2]))) >> 8;
#endif
if(font_rgb[0] == 0 && font_rgb[1] == 0 && font_rgb[2] == 0) mask_buf[mask_p] = LV_OPA_TRANSP;
else mask_buf[mask_p] = LV_OPA_COVER;
color_buf[mask_p] = res_color;
/*Next mask byte*/
mask_p++;
vdb_buf_tmp++;
}
/*Go to the next column*/
if(col_bit < 8 - g->bpp) {
col_bit += g->bpp;
bitmask = bitmask >> g->bpp;
} else {
col_bit = 0;
bitmask = bitmask_init;
map_p++;
}
}
/*Apply masks if any*/
if(other_mask_cnt) {
lv_draw_mask_res_t mask_res = lv_draw_mask_apply(mask_buf + mask_p_start, map_area.x1, map_area.y2, lv_area_get_width(&map_area));
if(mask_res == LV_DRAW_MASK_RES_FULL_TRANSP) {
memset(mask_buf + mask_p_start, 0x00, lv_area_get_width(&map_area));
}
}
if((uint32_t) mask_p + (row_end - row_start) < mask_buf_size) {
map_area.y2 ++;
} else {
lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, LV_BLEND_MODE_NORMAL);
map_area.y1 = map_area.y2 + 1;
map_area.y2 = map_area.y1;
mask_p = 0;
}
col_bit += ((g->box_w - col_end) + col_start) * g->bpp;
map_p += (col_bit >> 3);
col_bit = col_bit & 0x7;
/*Next row in VDB*/
vdb_buf_tmp += vdb_width - (col_end - col_start) / 3;
}
/*Flush the last part*/
if(map_area.y1 != map_area.y2) {
map_area.y2--;
lv_blend_map(clip_area, &map_area, color_buf, mask_buf, LV_DRAW_MASK_RES_CHANGED, opa, LV_BLEND_MODE_NORMAL);
}
lv_draw_buf_release(mask_buf);
lv_draw_buf_release(color_buf);
}
/**
* Convert a hexadecimal characters to a number (0..15)

View File

@@ -8,6 +8,8 @@
*********************/
#include "../lv_core/lv_debug.h"
#include "lv_img_cache.h"
#include "lv_img_decoder.h"
#include "lv_draw_img.h"
#include "../lv_hal/lv_hal_tick.h"
#include "../lv_misc/lv_gc.h"
@@ -80,7 +82,15 @@ lv_img_cache_entry_t * lv_img_cache_open(const void * src, const lv_style_t * st
/*Is the image cached?*/
lv_img_cache_entry_t * cached_src = NULL;
for(i = 0; i < entry_cnt; i++) {
if(cache[i].dec_dsc.src == src) {
bool match = false;
lv_img_src_t src_type = lv_img_src_get_type(cache[i].dec_dsc.src);
if(src_type == LV_IMG_SRC_VARIABLE) {
if(cache[i].dec_dsc.src == src) match = true;
} else if(src_type == LV_IMG_SRC_FILE) {
if(strcmp(cache[i].dec_dsc.src, src) == 0) match = true;
}
if(match) {
/* If opened increment its life.
* Image difficult to open should live longer to keep avoid frequent their recaching.
* Therefore increase `life` with `time_to_open`*/

View File

@@ -120,10 +120,17 @@ lv_res_t lv_img_decoder_get_info(const char * src, lv_img_header_t * header)
lv_res_t lv_img_decoder_open(lv_img_decoder_dsc_t * dsc, const void * src, const lv_style_t * style)
{
dsc->style = style;
dsc->src = src;
dsc->src_type = lv_img_src_get_type(src);
dsc->user_data = NULL;
if(dsc->src_type == LV_IMG_SRC_FILE) {
uint16_t fnlen = strlen(src);
dsc->src = lv_mem_alloc(fnlen + 1);
strcpy((char *)dsc->src, src);
} else {
dsc->src = src;
}
lv_res_t res = LV_RES_INV;
lv_img_decoder_t * d;
@@ -177,6 +184,11 @@ void lv_img_decoder_close(lv_img_decoder_dsc_t * dsc)
{
if(dsc->decoder) {
if(dsc->decoder->close_cb) dsc->decoder->close_cb(dsc->decoder, dsc);
if(dsc->src_type == LV_IMG_SRC_FILE) {
lv_mem_free(dsc->src);
dsc->src = NULL;
}
}
}

View File

@@ -53,7 +53,18 @@ typedef struct
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
}lv_font_glyph_dsc_t;
/*Describe the properties of a font*/
/** The bitmaps might be upscaled by 3 to achieve subpixel rendering. */
enum {
LV_FONT_SUBPX_NONE,
LV_FONT_SUBPX_HOR,
LV_FONT_SUBPX_VER,
LV_FONT_SUBPX_BOTH,
};
typedef uint8_t lv_font_subpx_t;
/** Describe the properties of a font*/
typedef struct _lv_font_struct
{
/** Get a glyph's descriptor from a font*/
@@ -69,6 +80,9 @@ typedef struct _lv_font_struct
#if LV_USE_USER_DATA
lv_font_user_data_t user_data; /**< Custom user data for font. */
#endif
uint32_t subpx :2; /**< An element of `lv_font_subpx_t`*/
} lv_font_t;
/**********************

View File

@@ -91,6 +91,7 @@ const uint8_t * lv_font_get_bitmap_fmt_txt(const lv_font_t * font, uint32_t unic
static uint8_t * buf = NULL;
uint32_t gsize = gdsc->box_w * gdsc->box_h;
if(gsize == 0) return NULL;
uint32_t buf_size = gsize;
switch(fdsc->bpp) {
case 1: buf_size = gsize >> 3; break;
@@ -138,7 +139,9 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
/*Put together a glyph dsc*/
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
uint32_t adv_w = gdsc->adv_w + ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
int32_t kv = ((int32_t)((int32_t)kvalue * fdsc->kern_scale) >> 4);
uint32_t adv_w = gdsc->adv_w + kv;
adv_w = (adv_w + (1 << 3)) >> 4;
dsc_out->adv_w = adv_w;

View File

@@ -45,7 +45,7 @@ typedef struct
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*/
int8_t ofs_y; /**< y offset of the bounding box. Measured from the top of the line*/
}lv_font_fmt_txt_glyph_dsc_t;
@@ -141,7 +141,7 @@ typedef struct {
3. value = class_pair_values[(left_class-1)*right_class_cnt + (righ_class-1)]
*/
const uint8_t * class_pair_values; /*left_class_num * right_class_num value*/
const int8_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*/
uint8_t left_class_cnt;
@@ -191,6 +191,7 @@ typedef struct {
* from `lv_font_fmt_txt_bitmap_format_t`
*/
uint16_t bitmap_format :2;
uint16_t subpx :1;
/*Cache the last letter and is glyph id*/
uint32_t last_letter;

View File

@@ -1,4 +1,4 @@
#include "lvgl/lvgl.h"
#include "../../lvgl.h"
/*******************************************************************************
* Size: 12 px

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
#include "lvgl/lvgl.h"
#include "../../lvgl.h"
/*******************************************************************************
* Size: 22 px

View File

@@ -1,4 +1,4 @@
#include "lvgl/lvgl.h"
#include "../../lvgl.h"
/*******************************************************************************
* Size: 28 px

View File

@@ -311,7 +311,7 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t gylph_bitmap[] = {
* GLYPH DESCRIPTION
*--------------------*/
static lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = {
{.bitmap_index = 0, .adv_w = 0, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0} /* id = 0 reserved */,
{.bitmap_index = 0, .adv_w = 128, .box_h = 0, .box_w = 0, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 0, .adv_w = 128, .box_h = 7, .box_w = 1, .ofs_x = 3, .ofs_y = -1},
@@ -460,4 +460,3 @@ lv_font_t lv_font_unscii_8 = {
};
#endif /*#if LV_FONT_UNSCII_8*/

View File

@@ -138,7 +138,7 @@ lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
disp->act_scr = lv_obj_create(NULL, NULL); /*Create a default screen on the display*/
disp->top_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create top layer on the display*/
disp->sys_layer = lv_obj_create(NULL, NULL); /*Create sys layer on the display*/
lv_obj_set_style(disp->top_layer, &lv_style_transp);
lv_obj_set_style(disp->sys_layer, &lv_style_transp);

View File

@@ -244,7 +244,7 @@ void lv_btnm_set_map(const lv_obj_t * btnm, const char * map[])
btn_i++;
}
}
act_y += btn_h + style_bg->body.padding.inner;
act_y += btn_h + style_bg->body.padding.inner + 1;
if(strlen(map_p_tmp[btn_cnt]) == 0) break; /*Break on end of map*/
map_p_tmp = &map_p_tmp[btn_cnt + 1]; /*Set the map to the next line*/

View File

@@ -1285,7 +1285,7 @@ static void lv_chart_draw_y_ticks(lv_obj_t * chart, const lv_area_t * mask, uint
const lv_style_t * style = lv_obj_get_style(chart);
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
uint8_t i, j;
uint8_t i;
uint8_t num_of_labels;
uint8_t num_scale_ticks;
int8_t major_tick_len, minor_tick_len;
@@ -1411,8 +1411,7 @@ static void lv_chart_draw_x_ticks(lv_obj_t * chart, const lv_area_t * mask)
const lv_style_t * style = lv_obj_get_style(chart);
lv_opa_t opa_scale = lv_obj_get_opa_scale(chart);
uint8_t i, j;
uint8_t list_index;
uint8_t i;
uint8_t num_of_labels;
uint8_t num_scale_ticks;
uint8_t major_tick_len, minor_tick_len;

View File

@@ -163,15 +163,20 @@ void lv_img_set_src(lv_obj_t * img, const void * src_img)
} else if(src_type == LV_IMG_SRC_FILE || src_type == LV_IMG_SRC_SYMBOL) {
/* If the new and the old src are the same then it was only a refresh.*/
if(ext->src != src_img) {
/*If memory was allocated because of the previous `src_type` then free it*/
const void * old_src = NULL;
/* If memory was allocated because of the previous `src_type` then save its pointer and free after allocation.
* It's important to allocate first to be sure the new data will be on a new address.
* Else `img_cache` wouldn't see the change in source.*/
if(ext->src_type == LV_IMG_SRC_FILE || ext->src_type == LV_IMG_SRC_SYMBOL) {
lv_mem_free(ext->src);
old_src = ext->src;
}
char * new_str = lv_mem_alloc(strlen(src_img) + 1);
LV_ASSERT_MEM(new_str);
if(new_str == NULL) return;
strcpy(new_str, src_img);
ext->src = new_str;
if(old_src) lv_mem_free(old_src);
}
}

View File

@@ -254,6 +254,8 @@ void lv_win_set_content_size(lv_obj_t * win, lv_coord_t w, lv_coord_t h)
lv_win_ext_t * ext = lv_obj_get_ext_attr(win);
h += lv_obj_get_height(ext->header);
lv_obj_set_size(win, w, h);
}
/**