From 9f29289afd6ec503a090dda52751b7ce97977a4c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mario=20Rubio=20G=C3=B3mez?= Date: Mon, 18 Mar 2019 07:25:20 +0100 Subject: [PATCH] Added lv_utils and moved functions "bsearch & num_to_str". --- lv_misc/lv_font.c | 22 +++---- lv_misc/lv_math.c | 100 ------------------------------- lv_misc/lv_math.h | 29 --------- lv_misc/lv_misc.mk | 1 + lv_misc/lv_utils.c | 136 ++++++++++++++++++++++++++++++++++++++++++ lv_misc/lv_utils.h | 65 ++++++++++++++++++++ lv_objx/lv_calendar.c | 6 +- lv_objx/lv_gauge.c | 3 +- lv_objx/lv_spinbox.c | 3 +- 9 files changed, 220 insertions(+), 145 deletions(-) create mode 100644 lv_misc/lv_utils.c create mode 100644 lv_misc/lv_utils.h diff --git a/lv_misc/lv_font.c b/lv_misc/lv_font.c index a0acd0f50..ed5550a7a 100644 --- a/lv_misc/lv_font.c +++ b/lv_misc/lv_font.c @@ -9,7 +9,7 @@ #include "lv_font.h" #include "lv_log.h" -#include "lv_math.h" +#include "lv_utils.h" /********************* * DEFINES @@ -221,11 +221,11 @@ const uint8_t * lv_font_get_bitmap_sparse(const lv_font_t * font, uint32_t unico uint32_t* pUnicode; - pUnicode = lv_bsearch(&unicode_letter, - (uint32_t*) font->unicode_list, - font->glyph_cnt, - sizeof(uint32_t), - lv_font_codeCompare); + pUnicode = lv_utils_bsearch(&unicode_letter, + (uint32_t*) font->unicode_list, + font->glyph_cnt, + sizeof(uint32_t), + lv_font_codeCompare); if (pUnicode != NULL) { uint32_t idx = (uint32_t) (pUnicode - font->unicode_list); @@ -265,11 +265,11 @@ int16_t lv_font_get_width_sparse(const lv_font_t * font, uint32_t unicode_letter uint32_t* pUnicode; - pUnicode = lv_bsearch(&unicode_letter, - (uint32_t*) font->unicode_list, - font->glyph_cnt, - sizeof(uint32_t), - lv_font_codeCompare); + pUnicode = lv_utils_bsearch(&unicode_letter, + (uint32_t*) font->unicode_list, + font->glyph_cnt, + sizeof(uint32_t), + lv_font_codeCompare); if (pUnicode != NULL) { uint32_t idx = (uint32_t) (pUnicode - font->unicode_list); diff --git a/lv_misc/lv_math.c b/lv_misc/lv_math.c index 4cf1f1219..534770af7 100644 --- a/lv_misc/lv_math.c +++ b/lv_misc/lv_math.c @@ -47,63 +47,6 @@ static int16_t sin0_90_table[] = { * GLOBAL FUNCTIONS **********************/ -/** - * Convert a number to string - * @param num a number - * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements) - * @return same as `buf` (just for convenience) - */ -char * lv_math_num_to_str(int32_t num, char * buf) -{ - char * buf_ori = buf; - if(num == 0) { - buf[0] = '0'; - buf[1] = '\0'; - return buf; - } else if(num < 0) { - (*buf) = '-'; - buf++; - num = LV_MATH_ABS(num); - } - uint32_t output = 0; - int8_t i; - - for(i = 31; i >= 0; i--) { - if((output & 0xF) >= 5) - output += 3; - if(((output & 0xF0) >> 4) >= 5) - output += (3 << 4); - if(((output & 0xF00) >> 8) >= 5) - output += (3 << 8); - if(((output & 0xF000) >> 12) >= 5) - output += (3 << 12); - if(((output & 0xF0000) >> 16) >= 5) - output += (3 << 16); - if(((output & 0xF00000) >> 20) >= 5) - output += (3 << 20); - if(((output & 0xF000000) >> 24) >= 5) - output += (3 << 24); - if(((output & 0xF0000000) >> 28) >= 5) - output += (3 << 28); - output = (output << 1) | ((num >> i) & 1); - } - - uint8_t digit; - bool leading_zero_ready = false; - for(i = 28; i >= 0; i -= 4) { - digit = ((output >> i) & 0xF) + '0'; - if(digit == '0' && leading_zero_ready == false) continue; - - leading_zero_ready = true; - (*buf) = digit; - buf++; - } - - (*buf) = '\0'; - - return buf_ori; -} - /** * Return with sinus of an angle * @param angle @@ -159,49 +102,6 @@ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3) } - -/** - * Performs a binary search within the given list. - * - * @note Code extracted out of https://github.com/torvalds/linux/blob/master/lib/bsearch.c - * - * @warning The contents of the array should already be in ascending sorted order - * under the provided comparison function. - * - * @note The key need not have the same type as the elements in - * the array, e.g. key could be a string and the comparison function - * could compare the string with the struct's name field. However, if - * the key and elements in the array are of the same type, you can use - * the same comparison function for both sort() and bsearch(). - * - * @param key pointer to item being searched for - * @param base pointer to first element to search - * @param num number of elements - * @param size size of each element - * @param cmp pointer to comparison function - */ -void * lv_bsearch(const void * key, const void * base, uint32_t num, uint32_t size, int32_t (* cmp)(const void * key, const void * elt)) -{ - const char * pivot; - int32_t result; - - while (num > 0) { - pivot = ((char*)base) + (num >> 1) * size; - result = cmp(key, pivot); - - if (result == 0) - return (void *)pivot; - - if (result > 0) { - base = pivot + size; - num--; - } - num >>= 1; - } - - return NULL; -} - /********************** * STATIC FUNCTIONS **********************/ diff --git a/lv_misc/lv_math.h b/lv_misc/lv_math.h index 6abc43815..fea5bc950 100644 --- a/lv_misc/lv_math.h +++ b/lv_misc/lv_math.h @@ -36,13 +36,6 @@ extern "C" { /********************** * GLOBAL PROTOTYPES **********************/ -/** - * Convert a number to string - * @param num a number - * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements) - * @return same as `buf` (just for convenience) - */ -char * lv_math_num_to_str(int32_t num, char * buf); /** * Return with sinus of an angle @@ -62,28 +55,6 @@ int16_t lv_trigo_sin(int16_t angle); */ int32_t lv_bezier3(uint32_t t, int32_t u0, int32_t u1, int32_t u2, int32_t u3); -/** - * Performs a binary search within the given list. - * - * @note Code extracted out of https://github.com/torvalds/linux/blob/master/lib/bsearch.c - * - * @warning The contents of the array should already be in ascending sorted order - * under the provided comparison function. - * - * @note The key need not have the same type as the elements in - * the array, e.g. key could be a string and the comparison function - * could compare the string with the struct's name field. However, if - * the key and elements in the array are of the same type, you can use - * the same comparison function for both sort() and bsearch(). - * - * @param key pointer to item being searched for - * @param base pointer to first element to search - * @param num number of elements - * @param size size of each element - * @param cmp pointer to comparison function (see #lv_font_codeCompare as a comparison function example) - */ -void * lv_bsearch(const void * key, const void * base, uint32_t num, uint32_t size, int32_t (* cmp)(const void * key, const void * elt)); - /********************** * MACROS **********************/ diff --git a/lv_misc/lv_misc.mk b/lv_misc/lv_misc.mk index 470f1230d..007df550d 100644 --- a/lv_misc/lv_misc.mk +++ b/lv_misc/lv_misc.mk @@ -12,6 +12,7 @@ CSRCS += lv_ufs.c CSRCS += lv_math.c CSRCS += lv_log.c CSRCS += lv_gc.c +CSRCS += lv_utils.c DEPPATH += --dep-path $(LVGL_DIR)/lvgl/lv_misc VPATH += :$(LVGL_DIR)/lvgl/lv_misc diff --git a/lv_misc/lv_utils.c b/lv_misc/lv_utils.c new file mode 100644 index 000000000..42cb25947 --- /dev/null +++ b/lv_misc/lv_utils.c @@ -0,0 +1,136 @@ +/** + * @file lv_utils.c + * + */ + +/********************* + * INCLUDES + *********************/ +#include + +#include "lv_utils.h" +#include "lv_math.h" + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * STATIC PROTOTYPES + **********************/ + +/********************** + * STATIC VARIABLES + **********************/ + +/********************** + * MACROS + **********************/ + +/********************** + * GLOBAL FUNCTIONS + **********************/ + +/** + * Convert a number to string + * @param num a number + * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements) + * @return same as `buf` (just for convenience) + */ +char * lv_utils_num_to_str(int32_t num, char * buf) +{ + char * buf_ori = buf; + if(num == 0) { + buf[0] = '0'; + buf[1] = '\0'; + return buf; + } else if(num < 0) { + (*buf) = '-'; + buf++; + num = LV_MATH_ABS(num); + } + uint32_t output = 0; + int8_t i; + + for(i = 31; i >= 0; i--) { + if((output & 0xF) >= 5) + output += 3; + if(((output & 0xF0) >> 4) >= 5) + output += (3 << 4); + if(((output & 0xF00) >> 8) >= 5) + output += (3 << 8); + if(((output & 0xF000) >> 12) >= 5) + output += (3 << 12); + if(((output & 0xF0000) >> 16) >= 5) + output += (3 << 16); + if(((output & 0xF00000) >> 20) >= 5) + output += (3 << 20); + if(((output & 0xF000000) >> 24) >= 5) + output += (3 << 24); + if(((output & 0xF0000000) >> 28) >= 5) + output += (3 << 28); + output = (output << 1) | ((num >> i) & 1); + } + + uint8_t digit; + bool leading_zero_ready = false; + for(i = 28; i >= 0; i -= 4) { + digit = ((output >> i) & 0xF) + '0'; + if(digit == '0' && leading_zero_ready == false) continue; + + leading_zero_ready = true; + (*buf) = digit; + buf++; + } + + (*buf) = '\0'; + + return buf_ori; +} + + +/** Searches base[0] to base[n - 1] for an item that matches *key. + * + * @note The function cmp must return negative if its first + * argument (the search key) is less that its second (a table entry), + * zero if equal, and positive if greater. + * + * @note Items in the array must be in ascending order. + * + * @param key Pointer to item being searched for + * @param base Pointer to first element to search + * @param n Number of elements + * @param size Size of each element + * @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function example) + * + * @return a pointer to a matching item, or NULL if none exists. + */ +void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, int32_t (* cmp)(const void * pRef, const void * pElement)) +{ + const char * middle; + int32_t c; + + for (middle = base; n != 0;) { + middle += (n/2) * size; + if ((c = (*cmp)(key, middle)) > 0) { + n = (n/2) - ((n&1) == 0); + base = (middle += size); + } else if (c < 0) { + n /= 2; + middle = base; + } else { + return (char *) middle; + } + } + return NULL; +} + +/********************** + * STATIC FUNCTIONS + **********************/ + + diff --git a/lv_misc/lv_utils.h b/lv_misc/lv_utils.h new file mode 100644 index 000000000..f39adc351 --- /dev/null +++ b/lv_misc/lv_utils.h @@ -0,0 +1,65 @@ +/** + * @file lv_utils.h + * + */ + +#ifndef LV_UTILS_H +#define LV_UTILS_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/********************* + * INCLUDES + *********************/ +#include +#include + +/********************* + * DEFINES + *********************/ + +/********************** + * TYPEDEFS + **********************/ + +/********************** + * GLOBAL PROTOTYPES + **********************/ +/** + * Convert a number to string + * @param num a number + * @param buf pointer to a `char` buffer. The result will be stored here (max 10 elements) + * @return same as `buf` (just for convenience) + */ +char * lv_utils_num_to_str(int32_t num, char * buf); + +/** Searches base[0] to base[n - 1] for an item that matches *key. + * + * @note The function cmp must return negative if its first + * argument (the search key) is less that its second (a table entry), + * zero if equal, and positive if greater. + * + * @note Items in the array must be in ascending order. + * + * @param key Pointer to item being searched for + * @param base Pointer to first element to search + * @param n Number of elements + * @param size Size of each element + * @param cmp Pointer to comparison function (see #lv_font_codeCompare as a comparison function example) + * + * @return a pointer to a matching item, or NULL if none exists. + */ +void * lv_utils_bsearch(const void * key, const void * base, uint32_t n, uint32_t size, int32_t (* cmp)(const void * pRef, const void * pElement)); + +/********************** + * MACROS + **********************/ + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif diff --git a/lv_objx/lv_calendar.c b/lv_objx/lv_calendar.c index 217c08d56..8df6e5dc6 100644 --- a/lv_objx/lv_calendar.c +++ b/lv_objx/lv_calendar.c @@ -11,7 +11,7 @@ #include "../lv_draw/lv_draw.h" #include "../lv_hal/lv_hal_indev.h" -#include "../lv_misc/lv_math.h" +#include "../lv_misc/lv_utils.h" #include "../lv_core/lv_indev.h" #include "../lv_themes/lv_theme.h" #include @@ -742,7 +742,7 @@ static void draw_header(lv_obj_t * calendar, const lv_area_t * mask) /*Add the year + month name*/ char txt_buf[64]; - lv_math_num_to_str(ext->showed_date.year, txt_buf); + lv_utils_num_to_str(ext->showed_date.year, txt_buf); txt_buf[4] = ' '; txt_buf[5] = '\0'; strcpy(&txt_buf[5], get_month_name(calendar, ext->showed_date.month)); @@ -913,7 +913,7 @@ static void draw_days(lv_obj_t * calendar, const lv_area_t * mask) else final_style = act_style; /*Write the day's number*/ - lv_math_num_to_str(day_cnt, buf); + lv_utils_num_to_str(day_cnt, buf); lv_draw_label(&label_area, mask, final_style, opa_scale, buf, LV_TXT_FLAG_CENTER, NULL); /*Go to the next day*/ diff --git a/lv_objx/lv_gauge.c b/lv_objx/lv_gauge.c index ad2ef8d92..e93997d32 100644 --- a/lv_objx/lv_gauge.c +++ b/lv_objx/lv_gauge.c @@ -14,6 +14,7 @@ #include "../lv_themes/lv_theme.h" #include "../lv_misc/lv_txt.h" #include "../lv_misc/lv_math.h" +#include "../lv_misc/lv_utils.h" #include #include @@ -370,7 +371,7 @@ static void lv_gauge_draw_scale(lv_obj_t * gauge, const lv_area_t * mask) int16_t scale_act = (int32_t)((int32_t)(max - min) * i) / (label_num - 1); scale_act += min; - lv_math_num_to_str(scale_act, scale_txt); + lv_utils_num_to_str(scale_act, scale_txt); lv_area_t label_cord; lv_point_t label_size; diff --git a/lv_objx/lv_spinbox.c b/lv_objx/lv_spinbox.c index 70fac33ce..90603f724 100644 --- a/lv_objx/lv_spinbox.c +++ b/lv_objx/lv_spinbox.c @@ -11,6 +11,7 @@ #if USE_LV_SPINBOX != 0 #include "../lv_themes/lv_theme.h" #include "../lv_misc/lv_math.h" +#include "../lv_misc/lv_utils.h" /********************* * DEFINES @@ -415,7 +416,7 @@ static void lv_spinbox_updatevalue(lv_obj_t * spinbox) char digits[64]; /*Convert the numbers to string (the sign is already handled so always covert positive number)*/ - lv_math_num_to_str(ext->value < 0 ? -ext->value : ext->value, digits); + lv_utils_num_to_str(ext->value < 0 ? -ext->value : ext->value, digits); /*Add leading zeros*/ int lz_cnt = ext->digit_count - (int)strlen(digits);