add subpx rendering
This commit is contained in:
@@ -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()`
|
||||
|
||||
@@ -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
|
||||
*==================*/
|
||||
|
||||
@@ -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
|
||||
*==================*/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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`*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
/**********************
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Size: 12 px
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Size: 22 px
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "../../lvgl.h"
|
||||
|
||||
/*******************************************************************************
|
||||
* Size: 28 px
|
||||
|
||||
@@ -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*/
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user