Merge branch 'feat-subpixel' into dev-6.1
This commit is contained in:
@@ -361,6 +361,12 @@ typedef void * lv_font_user_data_t;
|
|||||||
# define lv_vsnprintf vsnprintf
|
# define lv_vsnprintf vsnprintf
|
||||||
#endif /*LV_SPRINTF_CUSTOM*/
|
#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
|
* LV_OBJ SETTINGS
|
||||||
*==================*/
|
*==================*/
|
||||||
|
|||||||
@@ -504,6 +504,14 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif /*LV_SPRINTF_CUSTOM*/
|
#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
|
* LV_OBJ SETTINGS
|
||||||
*==================*/
|
*==================*/
|
||||||
|
|||||||
@@ -252,6 +252,7 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
bool g_ret = lv_font_get_glyph_dsc(font_p, &g, letter, '\0');
|
||||||
if(g_ret == false) return;
|
if(g_ret == false) return;
|
||||||
|
|
||||||
|
|
||||||
lv_coord_t pos_x = pos_p->x + g.ofs_x;
|
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;
|
lv_coord_t pos_y = pos_p->y + (font_p->line_height - font_p->base_line) - g.box_h - g.ofs_y;
|
||||||
|
|
||||||
@@ -300,17 +301,32 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
if(g.box_w & 0x7) width_byte_scr++;
|
if(g.box_w & 0x7) width_byte_scr++;
|
||||||
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
|
uint16_t width_bit = g.box_w * g.bpp; /*Letter width in bits*/
|
||||||
|
|
||||||
|
bool subpx = font_p->subpx == LV_FONT_SUBPX_NONE ? false : true;
|
||||||
|
|
||||||
/* Calculate the col/row start/end on the map*/
|
/* Calculate the col/row start/end on the map*/
|
||||||
lv_coord_t col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
lv_coord_t col_start;
|
||||||
lv_coord_t col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
lv_coord_t col_end;
|
||||||
lv_coord_t row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
lv_coord_t row_start;
|
||||||
lv_coord_t row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
lv_coord_t row_end;
|
||||||
|
|
||||||
|
if(subpx == false) {
|
||||||
|
col_start = pos_x >= mask_p->x1 ? 0 : mask_p->x1 - pos_x;
|
||||||
|
col_end = pos_x + g.box_w <= mask_p->x2 ? g.box_w : mask_p->x2 - pos_x + 1;
|
||||||
|
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||||
|
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||||
|
} else {
|
||||||
|
col_start = pos_x >= mask_p->x1 ? 0 : (mask_p->x1 - pos_x) * 3;
|
||||||
|
col_end = pos_x + g.box_w / 3 <= mask_p->x2 ? g.box_w : (mask_p->x2 - pos_x + 1) * 3;
|
||||||
|
row_start = pos_y >= mask_p->y1 ? 0 : mask_p->y1 - pos_y;
|
||||||
|
row_end = pos_y + g.box_h <= mask_p->y2 ? g.box_h : mask_p->y2 - pos_y + 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*Set a pointer on VDB to the first pixel of the letter*/
|
/*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;
|
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*/
|
/*If the letter is partially out of mask the move there on VDB*/
|
||||||
vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
if(subpx) vdb_buf_tmp += (row_start * vdb_width) + col_start / 3;
|
||||||
|
else vdb_buf_tmp += (row_start * vdb_width) + col_start;
|
||||||
|
|
||||||
/*Move on the map too*/
|
/*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);
|
||||||
@@ -326,37 +342,85 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
scr_transp = disp->driver.screen_transp;
|
scr_transp = disp->driver.screen_transp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
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++) {
|
for(row = row_start; row < row_end; row++) {
|
||||||
bitmask = bitmask_init >> col_bit;
|
bitmask = bitmask_init >> col_bit;
|
||||||
|
uint8_t sub_px_cnt = 0;
|
||||||
for(col = col_start; col < col_end; col++) {
|
for(col = col_start; col < col_end; col++) {
|
||||||
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];
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(disp->driver.set_px_cb) {
|
/*subpx == 0*/
|
||||||
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
if(subpx == false) {
|
||||||
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
if(letter_px != 0) {
|
||||||
} else if(vdb_buf_tmp->full != color.full) {
|
if(opa == LV_OPA_COVER) {
|
||||||
if(px_opa > LV_OPA_MAX)
|
px_opa = g.bpp == 8 ? letter_px : bpp_opa_table[letter_px];
|
||||||
*vdb_buf_tmp = color;
|
} else {
|
||||||
else if(px_opa > LV_OPA_MIN) {
|
px_opa = g.bpp == 8 ? (uint16_t)((uint16_t)letter_px * opa) >> 8
|
||||||
if(scr_transp == false) {
|
: (uint16_t)((uint16_t)bpp_opa_table[letter_px] * opa) >> 8;
|
||||||
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
}
|
||||||
} else {
|
|
||||||
|
if(disp->driver.set_px_cb) {
|
||||||
|
disp->driver.set_px_cb(&disp->driver, (uint8_t *)vdb->buf_act, vdb_width,
|
||||||
|
(col + pos_x) - vdb->area.x1, (row + pos_y) - vdb->area.y1, color, px_opa);
|
||||||
|
} else if(vdb_buf_tmp->full != color.full) {
|
||||||
|
if(px_opa > LV_OPA_MAX) {
|
||||||
|
*vdb_buf_tmp = color;
|
||||||
|
} else if(px_opa > LV_OPA_MIN) {
|
||||||
|
if(scr_transp == false) {
|
||||||
|
*vdb_buf_tmp = lv_color_mix(color, *vdb_buf_tmp, px_opa);
|
||||||
|
} else {
|
||||||
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||||
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
vdb_buf_tmp++;
|
||||||
|
}
|
||||||
|
/*Handle subpx drawing*/
|
||||||
|
else {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
font_rgb[sub_px_cnt] = px_opa;
|
||||||
|
} else {
|
||||||
|
font_rgb[sub_px_cnt] = 0;
|
||||||
|
}
|
||||||
|
sub_px_cnt ++;
|
||||||
|
|
||||||
|
if(sub_px_cnt == 3) {
|
||||||
|
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(scr_transp == false) {
|
||||||
|
vdb_buf_tmp->full = res_color.full;
|
||||||
|
#if LV_COLOR_DEPTH == 32 && LV_COLOR_SCREEN_TRANSP
|
||||||
|
} else {
|
||||||
|
*vdb_buf_tmp = color_mix_2_alpha(*vdb_buf_tmp, (*vdb_buf_tmp).ch.alpha, color, px_opa);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
sub_px_cnt = 0;
|
||||||
|
vdb_buf_tmp++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vdb_buf_tmp++;
|
|
||||||
|
|
||||||
if(col_bit < 8 - g.bpp) {
|
if(col_bit < 8 - g.bpp) {
|
||||||
col_bit += g.bpp;
|
col_bit += g.bpp;
|
||||||
@@ -367,11 +431,15 @@ void lv_draw_letter(const lv_point_t * pos_p, const lv_area_t * mask_p, const lv
|
|||||||
map_p++;
|
map_p++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
map_p += (col_bit >> 3);
|
||||||
col_bit = col_bit & 0x7;
|
col_bit = col_bit & 0x7;
|
||||||
vdb_buf_tmp += vdb_width - (col_end - col_start); /*Next row in VDB*/
|
|
||||||
|
/*Next row in VDB*/
|
||||||
|
if(subpx) vdb_buf_tmp += vdb_width - (col_end - col_start) / 3;
|
||||||
|
else vdb_buf_tmp += vdb_width - (col_end - col_start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,7 +53,18 @@ typedef struct
|
|||||||
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
uint8_t bpp; /**< Bit-per-pixel: 1, 2, 4, 8*/
|
||||||
}lv_font_glyph_dsc_t;
|
}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
|
typedef struct _lv_font_struct
|
||||||
{
|
{
|
||||||
/** Get a glyph's descriptor from a font*/
|
/** Get a glyph's descriptor from a font*/
|
||||||
@@ -65,10 +76,13 @@ typedef struct _lv_font_struct
|
|||||||
/*Pointer to the font in a font pack (must have the same line height)*/
|
/*Pointer to the font in a font pack (must have the same line height)*/
|
||||||
uint8_t line_height; /**< The real line height where any text fits*/
|
uint8_t line_height; /**< The real line height where any text fits*/
|
||||||
uint8_t base_line; /**< Base line measured from the top of the line_height*/
|
uint8_t base_line; /**< Base line measured from the top of the line_height*/
|
||||||
|
uint8_t subpx :2; /**< An element of `lv_font_subpx_t`*/
|
||||||
void * dsc; /**< Store implementation specific data here*/
|
void * dsc; /**< Store implementation specific data here*/
|
||||||
#if LV_USE_USER_DATA
|
#if LV_USE_USER_DATA
|
||||||
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
lv_font_user_data_t user_data; /**< Custom user data for font. */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
} lv_font_t;
|
} lv_font_t;
|
||||||
|
|
||||||
/**********************
|
/**********************
|
||||||
|
|||||||
@@ -140,7 +140,9 @@ bool lv_font_get_glyph_dsc_fmt_txt(const lv_font_t * font, lv_font_glyph_dsc_t *
|
|||||||
/*Put together a glyph dsc*/
|
/*Put together a glyph dsc*/
|
||||||
const lv_font_fmt_txt_glyph_dsc_t * gdsc = &fdsc->glyph_dsc[gid];
|
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;
|
adv_w = (adv_w + (1 << 3)) >> 4;
|
||||||
|
|
||||||
dsc_out->adv_w = adv_w;
|
dsc_out->adv_w = adv_w;
|
||||||
|
|||||||
@@ -191,6 +191,7 @@ typedef struct {
|
|||||||
* from `lv_font_fmt_txt_bitmap_format_t`
|
* from `lv_font_fmt_txt_bitmap_format_t`
|
||||||
*/
|
*/
|
||||||
uint16_t bitmap_format :2;
|
uint16_t bitmap_format :2;
|
||||||
|
uint16_t subpx :1;
|
||||||
|
|
||||||
/*Cache the last letter and is glyph id*/
|
/*Cache the last letter and is glyph id*/
|
||||||
uint32_t last_letter;
|
uint32_t last_letter;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user