various draw speed improvments

This commit is contained in:
Gabor Kiss-Vamosi
2020-02-09 10:48:34 +01:00
parent 369376892e
commit 114994fa8c
11 changed files with 491 additions and 447 deletions

View File

@@ -2072,7 +2072,7 @@ lv_style_int_t lv_obj_get_style_int(const lv_obj_t * obj, uint8_t part, lv_style
case LV_STYLE_BORDER_SIDE:
return LV_BORDER_SIDE_FULL;
case LV_STYLE_SIZE:
return LV_DPI / 10;
return LV_DPI / 20;
case LV_STYLE_SCALE_WIDTH:
return LV_DPI / 8;
case LV_STYLE_BG_GRAD_STOP:
@@ -2874,11 +2874,10 @@ static lv_design_res_t lv_obj_design(lv_obj_t * obj, const lv_area_t * clip_area
if(lv_obj_get_style_clip_corner(obj, LV_OBJ_PART_MAIN)) return LV_DESIGN_RES_MASKED;
if(lv_obj_get_style_bg_opa(obj, LV_OBJ_PART_MAIN) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_bg_blend_mode(obj, LV_OBJ_PART_MAIN) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_border_blend_mode(obj, LV_OBJ_PART_MAIN) != LV_BLEND_MODE_NORMAL) return LV_DESIGN_RES_NOT_COVER;
/*Can cover the area only if fully solid (no opacity)*/
if(lv_obj_get_style_bg_opa(obj, LV_OBJ_PART_MAIN) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
if(lv_obj_get_style_opa_scale(obj, LV_OBJ_PART_MAIN) < LV_OPA_MAX) return LV_DESIGN_RES_NOT_COVER;
return LV_DESIGN_RES_COVER;

View File

@@ -433,7 +433,7 @@ static lv_obj_t * lv_refr_get_top_obj(const lv_area_t * area_p, lv_obj_t * obj)
/*If this object is fully cover the draw area check the children too */
if(lv_area_is_in(area_p, &obj->coords, 0) && obj->hidden == 0) {
lv_design_res_t design_res = obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK);
lv_design_res_t design_res = obj->design_cb ? obj->design_cb(obj, area_p, LV_DESIGN_COVER_CHK) : LV_DESIGN_RES_NOT_COVER;
if(design_res == LV_DESIGN_RES_MASKED) return NULL;
lv_obj_t * i;
@@ -491,7 +491,7 @@ static void lv_refr_obj_and_children(lv_obj_t * top_p, const lv_area_t * mask_p)
}
/*Call the post draw design function of the parents of the to object*/
par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
if(par->design_cb) par->design_cb(par, mask_p, LV_DESIGN_DRAW_POST);
/*The new border will be there last parents,
*so the 'younger' brothers of parent will be refreshed*/
@@ -529,7 +529,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
if(union_ok != false) {
/* Redraw the object */
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_MAIN);
#if MASK_AREA_DEBUG
static lv_color_t debug_color = LV_COLOR_RED;
@@ -576,7 +576,7 @@ static void lv_refr_obj(lv_obj_t * obj, const lv_area_t * mask_ori_p)
}
/* If all the children are redrawn make 'post draw' design */
obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
if(obj->design_cb) obj->design_cb(obj, &obj_ext_mask, LV_DESIGN_DRAW_POST);
}
}

View File

@@ -89,6 +89,11 @@ void lv_draw_label(const lv_area_t * coords, const lv_area_t * mask, lv_draw_lab
/*No need to waste processor time if string is empty*/
if (txt[0] == '\0') return;
lv_area_t clipped_area;
bool clip_ok = lv_area_intersect(&clipped_area, coords, mask);
if(!clip_ok) return;
if((dsc->flag & LV_TXT_FLAG_EXPAND) == 0) {
/*Normally use the label's width as width*/
w = lv_area_get_width(coords);

View File

@@ -1,4 +1,4 @@
/**lip
/**
* @file lv_draw_line.c
*
*/

View File

@@ -170,7 +170,7 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
uint16_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(other_mask_cnt) simple_mode = false;
else if(dsc->bg_grad_dir != LV_GRAD_DIR_NONE) simple_mode = false;
else if(dsc->bg_grad_dir == LV_GRAD_DIR_HOR) simple_mode = false;
int16_t mask_rout_id = LV_MASK_ID_INV;
@@ -266,19 +266,21 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
lv_blend_fill(clip, &fill_area2,
grad_color, mask_buf + mask_ofs, mask_res, opa, dsc->bg_blend_mode);
} else {
if(grad_map == NULL) {
if(dsc->bg_grad_dir == LV_GRAD_DIR_HOR) {
lv_blend_map(clip, &fill_area, grad_map, mask_buf, mask_res, opa, dsc->bg_blend_mode);
} else if(dsc->bg_grad_dir == LV_GRAD_DIR_VER) {
lv_blend_fill(clip, &fill_area,
grad_color,mask_buf, mask_res, opa, dsc->bg_blend_mode);
} else if(other_mask_cnt != 0) {
lv_blend_fill(clip, &fill_area,
grad_color,mask_buf, mask_res, opa, dsc->bg_blend_mode);
} else {
lv_blend_map(clip, &fill_area, grad_map, mask_buf, mask_res, opa, dsc->bg_blend_mode);
}
}
fill_area.y1++;
fill_area.y2++;
}
if(simple_mode) {
if(dsc->bg_grad_dir == LV_GRAD_DIR_NONE && other_mask_cnt == 0) {
lv_area_t fill_area;
/*Central part*/
fill_area.x1 = coords_bg.x1 + rout;
@@ -287,13 +289,21 @@ static void draw_bg(const lv_area_t * coords, const lv_area_t * clip, lv_draw_re
fill_area.y2 = coords_bg.y1 + rout;
lv_blend_fill(clip, &fill_area,
grad_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
dsc->bg_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
fill_area.y1 = coords_bg.y2 - rout;
fill_area.y2 = coords_bg.y2;
lv_blend_fill(clip, &fill_area,
grad_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
dsc->bg_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
fill_area.x1 = coords_bg.x1;
fill_area.x2 = coords_bg.x2;
fill_area.y1 = coords_bg.y1 + rout + 1;
fill_area.y2 = coords_bg.y2 - rout - 1;
lv_blend_fill(clip, &fill_area,
dsc->bg_color, NULL, LV_DRAW_MASK_RES_FULL_COVER, opa, dsc->bg_blend_mode);
}
@@ -339,10 +349,10 @@ static void draw_border(const lv_area_t * coords, const lv_area_t * clip, lv_dra
/*Create a mask if there is a radius*/
lv_opa_t * mask_buf = lv_mem_buf_get(draw_area_w);
uint8_t other_mask_cnt = lv_draw_mask_get_cnt();
bool simple_mode = true;
if(lv_draw_mask_get_cnt()!= 0) simple_mode = false;
if(other_mask_cnt) simple_mode = false;
else if(dsc->border_side != LV_BORDER_SIDE_FULL) simple_mode = false;
else if(dsc->bg_grad_dir == LV_GRAD_DIR_HOR) simple_mode = false;
int16_t mask_rout_id = LV_MASK_ID_INV;
@@ -361,7 +371,6 @@ static void draw_border(const lv_area_t * coords, const lv_area_t * clip, lv_dra
mask_rout_id = lv_draw_mask_add(&mask_rout_param, NULL);
}
/*Get the inner radius*/
int32_t rin = rout - dsc->border_width;
if(rin < 0) rin = 0;
@@ -485,12 +494,18 @@ static void draw_border(const lv_area_t * coords, const lv_area_t * clip, lv_dra
fill_area.x2 = coords->x2;
fill_area.y1 = disp_area->y1 + draw_area.y1;
fill_area.y2 = fill_area.y1;
if(dsc->border_side == LV_BORDER_SIDE_LEFT) fill_area.x2 = coords->x1 + rout;
else if(dsc->border_side == LV_BORDER_SIDE_RIGHT) fill_area.x1 = coords->x2 - rout;
for(h = draw_area.y1; h <= draw_area.y2; h++) {
if((dsc->border_side == LV_BORDER_SIDE_BOTTOM && fill_area.y1 >= coords->y2 - rout - 1) ||
(dsc->border_side == LV_BORDER_SIDE_TOP && fill_area.y1 <= coords->y1 + rout + 1)) {
memset(mask_buf, LV_OPA_COVER, draw_area_w);
mask_res = lv_draw_mask_apply(mask_buf, vdb->area.x1 + draw_area.x1, vdb->area.y1 + h, draw_area_w);
lv_blend_fill( clip, &fill_area, color, mask_buf, mask_res, opa, blend_mode);
}
fill_area.y1++;
fill_area.y2++;

View File

@@ -587,8 +587,9 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
else if(mode == LV_DESIGN_DRAW_MAIN) {
ancestor_design_f(btnm, clip_area, mode);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
lv_btnm_ext_t * ext = lv_obj_get_ext_attr(btnm);
if(ext->btn_cnt == 0) return LV_DESIGN_RES_OK;
lv_area_t area_btnm;
lv_obj_get_coords(btnm, &area_btnm);
@@ -599,6 +600,7 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
uint16_t btn_i = 0;
uint16_t txt_i = 0;
lv_txt_flag_t txt_flag = LV_TXT_FLAG_NONE;
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
lv_draw_rect_dsc_t draw_rect_rel_dsc;
lv_draw_label_dsc_t draw_label_rel_dsc;
@@ -614,7 +616,6 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
/*The state changes without re-caching the styles, disable the use of cache*/
lv_obj_state_dsc_t state = btnm->state_dsc;
lv_obj_state_dsc_t state_ori = btnm->state_dsc;
btnm->state_dsc.act = LV_OBJ_STATE_NORMAL;
btnm->state_dsc.prev = btnm->state_dsc.act;
@@ -622,27 +623,15 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
lv_draw_label_dsc_init(&draw_label_rel_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_rel_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_rel_dsc);
btnm->state_dsc.act = LV_OBJ_STATE_CHECKED;
btnm->state_dsc.prev = btnm->state_dsc.act;
lv_draw_rect_dsc_init(&draw_rect_chk_dsc);
lv_draw_label_dsc_init(&draw_label_chk_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_chk_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_chk_dsc);
btnm->state_dsc.act = LV_OBJ_STATE_DISABLED;
btnm->state_dsc.prev = btnm->state_dsc.act;
lv_draw_rect_dsc_init(&draw_rect_ina_dsc);
lv_draw_label_dsc_init(&draw_label_ina_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_ina_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_ina_dsc);
draw_label_rel_dsc.flag = txt_flag;
btnm->state_dsc = state_ori;
bool chk_inited = false;
bool disabled_inited = false;
lv_style_int_t padding_top = lv_obj_get_style_pad_top(btnm, LV_BTNM_PART_BG);
lv_style_int_t padding_bottom = lv_obj_get_style_pad_bottom(btnm, LV_BTNM_PART_BG);
if(ext->recolor) txt_flag = LV_TXT_FLAG_RECOLOR;
for(btn_i = 0; btn_i < ext->btn_cnt; btn_i++, txt_i++) {
/*Search the next valid text in the map*/
while(strcmp(ext->map_p[txt_i], "\n") == 0) {
@@ -666,7 +655,32 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
lv_draw_label_dsc_t * draw_label_dsc_act;
bool tgl_state = button_get_tgl_state(ext->ctrl_bits[btn_i]);
if(tgl_state) {
if(!chk_inited) {
btnm->state_dsc.act = LV_OBJ_STATE_CHECKED;
btnm->state_dsc.prev = btnm->state_dsc.act;
lv_draw_rect_dsc_init(&draw_rect_chk_dsc);
lv_draw_label_dsc_init(&draw_label_chk_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_chk_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_chk_dsc);
draw_label_chk_dsc.flag = txt_flag;
btnm->state_dsc = state_ori;
chk_inited = true;
}
}
if(button_is_inactive(ext->ctrl_bits[btn_i])) {
if(!disabled_inited) {
btnm->state_dsc.act = LV_OBJ_STATE_DISABLED;
btnm->state_dsc.prev = btnm->state_dsc.act;
lv_draw_rect_dsc_init(&draw_rect_ina_dsc);
lv_draw_label_dsc_init(&draw_label_ina_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_ina_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_ina_dsc);
draw_label_ina_dsc.flag = txt_flag;
btnm->state_dsc = state_ori;
disabled_inited = true;
}
draw_rect_dsc_act = &draw_rect_ina_dsc;
draw_label_dsc_act = &draw_label_ina_dsc;
}
@@ -687,6 +701,7 @@ static lv_design_res_t lv_btnm_design(lv_obj_t * btnm, const lv_area_t * clip_ar
lv_draw_label_dsc_init(&draw_label_tmp_dsc);
lv_obj_init_draw_rect_dsc(btnm, LV_BTNM_PART_BTN, &draw_rect_tmp_dsc);
lv_obj_init_draw_label_dsc(btnm, LV_BTNM_PART_BTN, &draw_label_tmp_dsc);
draw_label_tmp_dsc.flag = txt_flag;
draw_rect_dsc_act = &draw_rect_tmp_dsc;
draw_label_dsc_act = &draw_label_tmp_dsc;

View File

@@ -806,7 +806,7 @@ static void draw_series_line(lv_obj_t * chart, const lv_area_t * series_area, co
point_dsc.bg_opa = line_dsc.opa;
point_dsc.radius = LV_RADIUS_CIRCLE;
lv_coord_t point_radius = lv_obj_get_style_radius(chart, LV_CHART_PART_SERIES);
lv_coord_t point_radius = lv_obj_get_style_size(chart, LV_CHART_PART_SERIES);
/*Go through all data lines*/
LV_LL_READ_BACK(ext->series_ll, ser)

View File

@@ -648,31 +648,37 @@ static lv_design_res_t lv_page_design(lv_obj_t * page, const lv_area_t * clip_ar
return ancestor_design(page, clip_area, mode);
} else if(mode == LV_DESIGN_DRAW_POST) {
ancestor_design(page, clip_area, mode);
/*Draw the scrollbars*/
lv_page_ext_t * ext = lv_obj_get_ext_attr(page);
lv_area_t sb_hor_area;
lv_area_t sb_ver_area;
sb_hor_area.x1 += page->coords.x1;
sb_hor_area.y1 += page->coords.y1;
sb_hor_area.x2 += page->coords.x1;
sb_hor_area.y2 += page->coords.y1;
sb_ver_area.x1 += page->coords.x1;
sb_ver_area.y1 += page->coords.y1;
sb_ver_area.x2 += page->coords.x1;
sb_ver_area.y2 += page->coords.y1;
if((ext->sb.hor_draw || ext->sb.ver_draw) &&
(lv_area_is_in(clip_area, &sb_hor_area, 0) || lv_area_is_in(clip_area, &sb_ver_area, 0))) {
/*Draw the scrollbars*/
lv_draw_rect_dsc_t rect_dsc;
lv_draw_rect_dsc_init(&rect_dsc);
lv_obj_init_draw_rect_dsc(page, LV_PAGE_PART_SCRLBAR, &rect_dsc);
lv_area_t sb_area;
if(ext->sb.hor_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {
/*Convert the relative coordinates to absolute*/
lv_area_copy(&sb_area, &ext->sb.hor_area);
sb_area.x1 += page->coords.x1;
sb_area.y1 += page->coords.y1;
sb_area.x2 += page->coords.x1;
sb_area.y2 += page->coords.y1;
lv_draw_rect(&sb_area, clip_area, &rect_dsc);
lv_area_copy(&sb_hor_area, &ext->sb.hor_area);
lv_draw_rect(&sb_hor_area, clip_area, &rect_dsc);
}
if(ext->sb.ver_draw && (ext->sb.mode & LV_SB_MODE_HIDE) == 0) {
/*Convert the relative coordinates to absolute*/
lv_area_copy(&sb_area, &ext->sb.ver_area);
sb_area.x1 += page->coords.x1;
sb_area.y1 += page->coords.y1;
sb_area.x2 += page->coords.x1;
sb_area.y2 += page->coords.y1;
lv_draw_rect(&sb_area, clip_area, &rect_dsc);
lv_area_copy(&sb_ver_area, &ext->sb.ver_area);
lv_draw_rect(&sb_ver_area, clip_area, &rect_dsc);
}
}
#if LV_USE_ANIMATION
@@ -715,7 +721,6 @@ static lv_design_res_t lv_page_design(lv_obj_t * page, const lv_area_t * clip_ar
lv_draw_rect(&flash_area, clip_area, &edge_draw_dsc);
}
}
#endif
}

View File

@@ -102,7 +102,7 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
/*The signal and design functions are not copied so set them here*/
lv_obj_set_signal_cb(tabview, lv_tabview_signal);
// lv_obj_set_design_cb(tabview, NULL);
/*Init the new tab tab*/
if(copy == NULL) {
ext->tab_name_ptr = lv_mem_alloc(sizeof(char *));
@@ -129,6 +129,11 @@ lv_obj_t * lv_tabview_create(lv_obj_t * par, const lv_obj_t * copy)
ext->btns = lv_btnm_create(tabview, NULL);
ext->indic = lv_obj_create(ext->btns, NULL);
// lv_obj_set_design_cb(ext->content, NULL);
// lv_obj_set_design_cb(lv_page_get_scrl(ext->content), NULL);
// lv_obj_set_design_cb(ext->btns, NULL);
// lv_obj_set_design_cb(ext->indic, NULL);
if(ancestor_scrl_signal == NULL) ancestor_scrl_signal = lv_obj_get_signal_cb(lv_page_get_scrl(ext->content));
lv_obj_set_signal_cb(lv_page_get_scrl(ext->content), tabview_scrl_signal);

View File

@@ -134,7 +134,7 @@ static void basic_init(void)
lv_style_set_bg_color(&scr, LV_STYLE_STATE_NORMAL, COLOR_SCREEN);
lv_style_set_text_color(&scr, LV_STYLE_STATE_NORMAL, lv_color_hex(0xb8b8b9));
#define PERF_TEST 3
#define PERF_TEST 0
#if PERF_TEST == 0
lv_style_init(&panel);
lv_style_set_radius(&panel, LV_STYLE_STATE_NORMAL, LV_DPI / 25);

View File

@@ -1,339 +1,339 @@
/**
* @file lv_test_assert.c
*
* Copyright 2002-2010 Guillaume Cottenceau.
*
* This software may be freely redistributed under the terms
* of the X11 license.
*
*/
/*********************
* INCLUDES
*********************/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#define PNG_DEBUG 3
#include <png.h>
#include "lv_test_assert.h"
#include "../lvgl.h"
/*********************
* DEFINES
*********************/
#define REF_IMGS_PATH "lvgl/tests/lv_test_ref_imgs/"
/**********************
* TYPEDEFS
**********************/
typedef struct {
int width, height;
png_byte color_type;
png_byte bit_depth;
png_structp png_ptr;
png_infop info_ptr;
int number_of_passes;
png_bytep * row_pointers;
}png_img_t;
/**********************
* STATIC PROTOTYPES
**********************/
void read_png_file(png_img_t * p, const char* file_name);
void write_png_file(png_img_t * p, const char* file_name);
void png_release(png_img_t * p);
/**********************
* STATIC VARIABLES
**********************/
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
void lv_test_print(const char * s, ...)
{
va_list args;
va_start(args, s);
vfprintf(stdout, s, args);
fprintf(stdout, "\n");
va_end(args);
}
void lv_test_exit(const char * s, ...)
{
va_list args;
va_start(args, s);
vfprintf(stderr, s, args);
fprintf(stderr, "\n");
va_end(args);
exit(1);
}
void lv_test_error(const char * s, ...)
{
va_list args;
va_start(args, s);
vfprintf(stderr, s, args);
fprintf(stderr, "\n");
va_end(args);
exit(1);
}
void lv_test_assert_int_eq(int32_t n_ref, int32_t n_act, const char * s)
{
if(n_ref != n_act) {
lv_test_error(" FAIL: %s. (Expected: %d, Actual: %d)", s, n_ref, n_act);
} else {
lv_test_print(" PASS: %s. (Expected: %d)", s, n_ref);
}
}
void lv_test_assert_int_gt(int32_t n_ref, int32_t n_act, const char * s)
{
if(n_act <= n_ref) {
lv_test_error(" FAIL: %s. (Expected: > %d, Actual: %d)", s, n_ref, n_act);
} else {
lv_test_print(" PASS: %s. (Expected: > %d, , Actual: %d)", s, n_ref, n_act);
}
}
void lv_test_assert_int_lt(int32_t n_ref, int32_t n_act, const char * s)
{
if(n_act >= n_ref) {
lv_test_error(" FAIL: %s. (Expected: < %d, Actual: %d)", s, n_ref, n_act);
} else {
lv_test_print(" PASS: %s. (Expected: < %d, , Actual: %d)", s, n_ref, n_act);
}
}
void lv_test_assert_str_eq(const char * s_ref, const char * s_act, const char * s)
{
if(strcmp(s_ref, s_act) != 0) {
lv_test_error(" FAIL: %s. (Expected: %s, Actual: %s)", s, s_ref, s_act);
} else {
lv_test_print(" PASS: %s. (Expected: %s)", s, s_ref);
}
}
void lv_test_assert_ptr_eq(const void * p_ref, const void * p_act, const char * s)
{
if(p_ref != p_act) {
lv_test_error(" FAIL: %s. (Expected: 0x%lx, Actual: 0x%lx)", s, p_ref, p_act);
} else {
lv_test_print(" PASS: %s. (Expected: 0x%lx)", s, p_ref);
}
}
void lv_test_assert_color_eq(lv_color_t c_ref, lv_color_t c_act, const char * s)
{
if(c_ref.full != c_act.full) {
lv_test_error(" FAIL: %s. (Expected: R:%02x, G:%02x, B:%02x, Actual: R:%02x, G:%02x, B:%02x)", s,
c_ref.ch.red, c_ref.ch.green, c_ref.ch.blue,
c_act.ch.red, c_act.ch.green, c_act.ch.blue);
} else {
lv_test_print(" PASS: %s. (Expected: R:%02x, G:%02x, B:%02x)", s,
c_ref.ch.red, c_ref.ch.green, c_ref.ch.blue);
}
}
void lv_test_assert_img_eq(const char * fn_ref, const char * s)
{
char fn_ref_full[512];
sprintf(fn_ref_full, "%s%s", REF_IMGS_PATH, fn_ref);
png_img_t p;
read_png_file(&p, fn_ref_full);
uint8_t * screen_buf;
lv_disp_t * disp = lv_disp_get_default();
lv_refr_now(disp);
screen_buf = disp->driver.buffer->buf1;
bool err = false;
int x, y, i_buf = 0;
for (y=0; y<p.height; y++) {
png_byte* row = p.row_pointers[y];
for (x=0; x<p.width; x++) {
const png_byte* ptr_ref = &(row[x*3]);
uint8_t * ptr_act = &(screen_buf[i_buf*4]);
uint8_t tmp = ptr_act[0];
ptr_act[0] = ptr_act[2];
ptr_act[2] = tmp;
if(memcmp(ptr_act, ptr_ref, 3) != 0) {
err = true;
break;
}
i_buf++;
}
if(err) break;
}
png_release(&p);
if(err) {
lv_test_error(" FAIL: %s. (Expected: %s)", s, fn_ref);
} else {
lv_test_print(" PASS: %s. (Expected: %s)", s, fn_ref);
}
}
/**********************
* STATIC FUNCTIONS
**********************/
void read_png_file(png_img_t * p, const char* file_name)
{
char header[8]; // 8 is the maximum size that can be checked
/* open file and test for it being a png */
FILE *fp = fopen(file_name, "rb");
if (!fp)
lv_test_exit("[read_png_file] File %s could not be opened for reading", file_name);
fread(header, 1, 8, fp);
if (png_sig_cmp((png_const_bytep)header, 0, 8))
lv_test_exit("[read_png_file] File %s is not recognized as a PNG file", file_name);
/* initialize stuff */
p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!p->png_ptr)
lv_test_exit("[read_png_file] png_create_read_struct failed");
p->info_ptr = png_create_info_struct(p->png_ptr);
if (!p->info_ptr)
lv_test_exit("[read_png_file] png_create_info_struct failed");
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[read_png_file] Error during init_io");
png_init_io(p->png_ptr, fp);
png_set_sig_bytes(p->png_ptr, 8);
png_read_info(p->png_ptr, p->info_ptr);
p->width = png_get_image_width(p->png_ptr, p->info_ptr);
p->height = png_get_image_height(p->png_ptr, p->info_ptr);
p->color_type = png_get_color_type(p->png_ptr, p->info_ptr);
p->bit_depth = png_get_bit_depth(p->png_ptr, p->info_ptr);
p->number_of_passes = png_set_interlace_handling(p->png_ptr);
png_read_update_info(p->png_ptr, p->info_ptr);
/* read file */
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[read_png_file] Error during read_image");
p->row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * p->height);
int y;
for (y=0; y<p->height; y++)
p->row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(p->png_ptr,p->info_ptr));
png_read_image(p->png_ptr, p->row_pointers);
fclose(fp);
}
void write_png_file(png_img_t * p, const char* file_name)
{
/* create file */
FILE *fp = fopen(file_name, "wb");
if (!fp)
lv_test_exit("[write_png_file] File %s could not be opened for writing", file_name);
/* initialize stuff */
p->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
if (!p->png_ptr)
lv_test_exit("[write_png_file] png_create_write_struct failed");
p->info_ptr = png_create_info_struct(p->png_ptr);
if (!p->info_ptr)
lv_test_exit("[write_png_file] png_create_info_struct failed");
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[write_png_file] Error during init_io");
png_init_io(p->png_ptr, fp);
/* write header */
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[write_png_file] Error during writing header");
png_set_IHDR(p->png_ptr, p->info_ptr, p->width, p->height,
p->bit_depth, p->color_type, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(p->png_ptr, p->info_ptr);
/* write bytes */
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[write_png_file] Error during writing bytes");
png_write_image(p->png_ptr, p->row_pointers);
/* end write */
if (setjmp(png_jmpbuf(p->png_ptr)))
lv_test_exit("[write_png_file] Error during end of write");
png_write_end(p->png_ptr, NULL);
fclose(fp);
}
void png_release(png_img_t * p)
{
int y;
for (y=0; y<p->height; y++)
free(p->row_pointers[y]);
free(p->row_pointers);
}
void process_file(png_img_t * p)
{
if (png_get_color_type(p->png_ptr, p->info_ptr) == PNG_COLOR_TYPE_RGB)
lv_test_exit("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA "
"(lacks the alpha channel)");
if (png_get_color_type(p->png_ptr, p->info_ptr) != PNG_COLOR_TYPE_RGBA)
lv_test_exit("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)",
PNG_COLOR_TYPE_RGBA, png_get_color_type(p->png_ptr, p->info_ptr));
int x, y;
for (y=0; y<p->height; y++) {
png_byte* row = p->row_pointers[y];
for (x=0; x<p->width; x++) {
png_byte* ptr = &(row[x*4]);
printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n",
x, y, ptr[0], ptr[1], ptr[2], ptr[3]);
/* set red value to 0 and green value to the blue one */
ptr[0] = 0;
ptr[1] = ptr[2];
}
}
}
///**
// * @file lv_test_assert.c
// *
// * Copyright 2002-2010 Guillaume Cottenceau.
// *
// * This software may be freely redistributed under the terms
// * of the X11 license.
// *
// */
//
///*********************
// * INCLUDES
// *********************/
//#include <unistd.h>
//#include <stdlib.h>
//#include <stdio.h>
//#include <string.h>
//#include <stdarg.h>
//
//#define PNG_DEBUG 3
//#include <png.h>
//
//#include "lv_test_assert.h"
//#include "../lvgl.h"
//
///*********************
// * DEFINES
// *********************/
//#define REF_IMGS_PATH "lvgl/tests/lv_test_ref_imgs/"
//
///**********************
// * TYPEDEFS
// **********************/
//typedef struct {
// int width, height;
// png_byte color_type;
// png_byte bit_depth;
//
// png_structp png_ptr;
// png_infop info_ptr;
// int number_of_passes;
// png_bytep * row_pointers;
//}png_img_t;
//
///**********************
// * STATIC PROTOTYPES
// **********************/
//void read_png_file(png_img_t * p, const char* file_name);
//void write_png_file(png_img_t * p, const char* file_name);
//void png_release(png_img_t * p);
//
///**********************
// * STATIC VARIABLES
// **********************/
//
///**********************
// * MACROS
// **********************/
//
///**********************
// * GLOBAL FUNCTIONS
// **********************/
//
//
//void lv_test_print(const char * s, ...)
//{
// va_list args;
// va_start(args, s);
// vfprintf(stdout, s, args);
// fprintf(stdout, "\n");
// va_end(args);
//}
//
//
//void lv_test_exit(const char * s, ...)
//{
// va_list args;
// va_start(args, s);
// vfprintf(stderr, s, args);
// fprintf(stderr, "\n");
// va_end(args);
//
// exit(1);
//}
//
//
//void lv_test_error(const char * s, ...)
//{
// va_list args;
// va_start(args, s);
// vfprintf(stderr, s, args);
// fprintf(stderr, "\n");
// va_end(args);
// exit(1);
//}
//
//void lv_test_assert_int_eq(int32_t n_ref, int32_t n_act, const char * s)
//{
// if(n_ref != n_act) {
// lv_test_error(" FAIL: %s. (Expected: %d, Actual: %d)", s, n_ref, n_act);
// } else {
// lv_test_print(" PASS: %s. (Expected: %d)", s, n_ref);
// }
//}
//
//void lv_test_assert_int_gt(int32_t n_ref, int32_t n_act, const char * s)
//{
// if(n_act <= n_ref) {
// lv_test_error(" FAIL: %s. (Expected: > %d, Actual: %d)", s, n_ref, n_act);
// } else {
// lv_test_print(" PASS: %s. (Expected: > %d, , Actual: %d)", s, n_ref, n_act);
// }
//}
//
//void lv_test_assert_int_lt(int32_t n_ref, int32_t n_act, const char * s)
//{
// if(n_act >= n_ref) {
// lv_test_error(" FAIL: %s. (Expected: < %d, Actual: %d)", s, n_ref, n_act);
// } else {
// lv_test_print(" PASS: %s. (Expected: < %d, , Actual: %d)", s, n_ref, n_act);
// }
//}
//
//
//void lv_test_assert_str_eq(const char * s_ref, const char * s_act, const char * s)
//{
// if(strcmp(s_ref, s_act) != 0) {
// lv_test_error(" FAIL: %s. (Expected: %s, Actual: %s)", s, s_ref, s_act);
// } else {
// lv_test_print(" PASS: %s. (Expected: %s)", s, s_ref);
// }
//}
//
//void lv_test_assert_ptr_eq(const void * p_ref, const void * p_act, const char * s)
//{
// if(p_ref != p_act) {
// lv_test_error(" FAIL: %s. (Expected: 0x%lx, Actual: 0x%lx)", s, p_ref, p_act);
// } else {
// lv_test_print(" PASS: %s. (Expected: 0x%lx)", s, p_ref);
// }
//}
//
//void lv_test_assert_color_eq(lv_color_t c_ref, lv_color_t c_act, const char * s)
//{
// if(c_ref.full != c_act.full) {
// lv_test_error(" FAIL: %s. (Expected: R:%02x, G:%02x, B:%02x, Actual: R:%02x, G:%02x, B:%02x)", s,
// c_ref.ch.red, c_ref.ch.green, c_ref.ch.blue,
// c_act.ch.red, c_act.ch.green, c_act.ch.blue);
// } else {
// lv_test_print(" PASS: %s. (Expected: R:%02x, G:%02x, B:%02x)", s,
// c_ref.ch.red, c_ref.ch.green, c_ref.ch.blue);
// }
//}
//
//void lv_test_assert_img_eq(const char * fn_ref, const char * s)
//{
// char fn_ref_full[512];
// sprintf(fn_ref_full, "%s%s", REF_IMGS_PATH, fn_ref);
//
// png_img_t p;
// read_png_file(&p, fn_ref_full);
// uint8_t * screen_buf;
//
// lv_disp_t * disp = lv_disp_get_default();
// lv_refr_now(disp);
// screen_buf = disp->driver.buffer->buf1;
//
// bool err = false;
// int x, y, i_buf = 0;
// for (y=0; y<p.height; y++) {
// png_byte* row = p.row_pointers[y];
// for (x=0; x<p.width; x++) {
// const png_byte* ptr_ref = &(row[x*3]);
// uint8_t * ptr_act = &(screen_buf[i_buf*4]);
// uint8_t tmp = ptr_act[0];
// ptr_act[0] = ptr_act[2];
// ptr_act[2] = tmp;
//
// if(memcmp(ptr_act, ptr_ref, 3) != 0) {
// err = true;
// break;
// }
// i_buf++;
// }
// if(err) break;
// }
//
// png_release(&p);
//
// if(err) {
// lv_test_error(" FAIL: %s. (Expected: %s)", s, fn_ref);
// } else {
// lv_test_print(" PASS: %s. (Expected: %s)", s, fn_ref);
// }
//}
//
///**********************
// * STATIC FUNCTIONS
// **********************/
//
//void read_png_file(png_img_t * p, const char* file_name)
//{
// char header[8]; // 8 is the maximum size that can be checked
//
// /* open file and test for it being a png */
// FILE *fp = fopen(file_name, "rb");
// if (!fp)
// lv_test_exit("[read_png_file] File %s could not be opened for reading", file_name);
// fread(header, 1, 8, fp);
// if (png_sig_cmp((png_const_bytep)header, 0, 8))
// lv_test_exit("[read_png_file] File %s is not recognized as a PNG file", file_name);
//
//
// /* initialize stuff */
// p->png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
//
// if (!p->png_ptr)
// lv_test_exit("[read_png_file] png_create_read_struct failed");
//
// p->info_ptr = png_create_info_struct(p->png_ptr);
// if (!p->info_ptr)
// lv_test_exit("[read_png_file] png_create_info_struct failed");
//
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[read_png_file] Error during init_io");
//
// png_init_io(p->png_ptr, fp);
// png_set_sig_bytes(p->png_ptr, 8);
//
// png_read_info(p->png_ptr, p->info_ptr);
//
// p->width = png_get_image_width(p->png_ptr, p->info_ptr);
// p->height = png_get_image_height(p->png_ptr, p->info_ptr);
// p->color_type = png_get_color_type(p->png_ptr, p->info_ptr);
// p->bit_depth = png_get_bit_depth(p->png_ptr, p->info_ptr);
//
// p->number_of_passes = png_set_interlace_handling(p->png_ptr);
// png_read_update_info(p->png_ptr, p->info_ptr);
//
//
// /* read file */
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[read_png_file] Error during read_image");
//
// p->row_pointers = (png_bytep*) malloc(sizeof(png_bytep) * p->height);
//
// int y;
// for (y=0; y<p->height; y++)
// p->row_pointers[y] = (png_byte*) malloc(png_get_rowbytes(p->png_ptr,p->info_ptr));
//
// png_read_image(p->png_ptr, p->row_pointers);
//
// fclose(fp);
//}
//
//
//void write_png_file(png_img_t * p, const char* file_name)
//{
// /* create file */
// FILE *fp = fopen(file_name, "wb");
// if (!fp)
// lv_test_exit("[write_png_file] File %s could not be opened for writing", file_name);
//
//
// /* initialize stuff */
// p->png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
//
// if (!p->png_ptr)
// lv_test_exit("[write_png_file] png_create_write_struct failed");
//
// p->info_ptr = png_create_info_struct(p->png_ptr);
// if (!p->info_ptr)
// lv_test_exit("[write_png_file] png_create_info_struct failed");
//
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[write_png_file] Error during init_io");
//
// png_init_io(p->png_ptr, fp);
//
//
// /* write header */
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[write_png_file] Error during writing header");
//
// png_set_IHDR(p->png_ptr, p->info_ptr, p->width, p->height,
// p->bit_depth, p->color_type, PNG_INTERLACE_NONE,
// PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
//
// png_write_info(p->png_ptr, p->info_ptr);
//
//
// /* write bytes */
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[write_png_file] Error during writing bytes");
//
// png_write_image(p->png_ptr, p->row_pointers);
//
//
// /* end write */
// if (setjmp(png_jmpbuf(p->png_ptr)))
// lv_test_exit("[write_png_file] Error during end of write");
//
// png_write_end(p->png_ptr, NULL);
//
// fclose(fp);
//}
//
//void png_release(png_img_t * p)
//{
// int y;
// for (y=0; y<p->height; y++)
// free(p->row_pointers[y]);
// free(p->row_pointers);
//}
//
//void process_file(png_img_t * p)
//{
// if (png_get_color_type(p->png_ptr, p->info_ptr) == PNG_COLOR_TYPE_RGB)
// lv_test_exit("[process_file] input file is PNG_COLOR_TYPE_RGB but must be PNG_COLOR_TYPE_RGBA "
// "(lacks the alpha channel)");
//
// if (png_get_color_type(p->png_ptr, p->info_ptr) != PNG_COLOR_TYPE_RGBA)
// lv_test_exit("[process_file] color_type of input file must be PNG_COLOR_TYPE_RGBA (%d) (is %d)",
// PNG_COLOR_TYPE_RGBA, png_get_color_type(p->png_ptr, p->info_ptr));
//
// int x, y;
// for (y=0; y<p->height; y++) {
// png_byte* row = p->row_pointers[y];
// for (x=0; x<p->width; x++) {
// png_byte* ptr = &(row[x*4]);
// printf("Pixel at position [ %d - %d ] has RGBA values: %d - %d - %d - %d\n",
// x, y, ptr[0], ptr[1], ptr[2], ptr[3]);
//
// /* set red value to 0 and green value to the blue one */
// ptr[0] = 0;
// ptr[1] = ptr[2];
// }
// }
//}