feat(tests): add freetype font stress tests (#5828)
@ -289,9 +289,19 @@ endif()
|
||||
|
||||
# disable test targets for build only tests
|
||||
if (ENABLE_TESTS)
|
||||
file( GLOB_RECURSE TEST_CASE_FILES src/test_cases/*.c )
|
||||
file(GLOB_RECURSE TEST_CASE_FILES src/test_cases/*.c)
|
||||
file(GLOB_RECURSE TEST_LIBS_FILES src/test_libs/*.c)
|
||||
else()
|
||||
set(TEST_CASE_FILES)
|
||||
set(TEST_LIBS_FILES)
|
||||
endif()
|
||||
|
||||
# build a test libs target
|
||||
if (TEST_LIBS_FILES)
|
||||
add_library(test_libs STATIC ${TEST_LIBS_FILES})
|
||||
target_include_directories(test_libs PUBLIC ${TEST_INCLUDE_DIRS} "src/test_libs")
|
||||
target_compile_options(test_libs PUBLIC ${LVGL_TESTFILE_COMPILE_OPTIONS})
|
||||
list(APPEND TEST_LIBS test_libs)
|
||||
endif()
|
||||
|
||||
foreach( test_case_fname ${TEST_CASE_FILES} )
|
||||
|
BIN
tests/ref_imgs/libs/font_stress/snapshot_0.lp32.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_0.lp64.png
Normal file
After Width: | Height: | Size: 51 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_1.lp32.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_1.lp64.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_10.lp32.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_10.lp64.png
Normal file
After Width: | Height: | Size: 54 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_2.lp32.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_2.lp64.png
Normal file
After Width: | Height: | Size: 136 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_3.lp32.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_3.lp64.png
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_4.lp32.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_4.lp64.png
Normal file
After Width: | Height: | Size: 86 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_5.lp32.png
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_5.lp64.png
Normal file
After Width: | Height: | Size: 117 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_6.lp32.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_6.lp64.png
Normal file
After Width: | Height: | Size: 87 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_7.lp32.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_7.lp64.png
Normal file
After Width: | Height: | Size: 103 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_8.lp32.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_8.lp64.png
Normal file
After Width: | Height: | Size: 75 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_9.lp32.png
Normal file
After Width: | Height: | Size: 91 KiB |
BIN
tests/ref_imgs/libs/font_stress/snapshot_9.lp64.png
Normal file
After Width: | Height: | Size: 91 KiB |
209
tests/src/test_cases/libs/test_font_stress.c
Normal file
@ -0,0 +1,209 @@
|
||||
#if LV_BUILD_TEST
|
||||
#include "../lvgl.h"
|
||||
|
||||
#include "unity/unity.h"
|
||||
|
||||
#if LV_USE_FREETYPE
|
||||
|
||||
#include "rnd_unicodes/lv_rnd_unicodes.h"
|
||||
|
||||
#if __WORDSIZE == 64
|
||||
#define TEST_FREETYPE_ASSERT_EQUAL_SCREENSHOT(INDEX) \
|
||||
lv_snprintf(buf, sizeof(buf), "libs/font_stress/snapshot_%0d.lp64.png", (INDEX));\
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT(buf)
|
||||
#elif __WORDSIZE == 32
|
||||
#define TEST_FREETYPE_ASSERT_EQUAL_SCREENSHOT(INDEX) \
|
||||
lv_snprintf(buf, sizeof(buf), "libs/font_stress/snapshot_%0d.lp32.png", (INDEX));\
|
||||
TEST_ASSERT_EQUAL_SCREENSHOT(buf)
|
||||
#endif
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
const char ** font_name_arr;
|
||||
int font_cnt;
|
||||
int label_cnt;
|
||||
int loop_cnt;
|
||||
} lvx_font_stress_config_t;
|
||||
|
||||
typedef struct {
|
||||
lv_obj_t * par;
|
||||
lv_obj_t ** label_arr;
|
||||
lvx_font_stress_config_t config;
|
||||
} stress_test_ctx_t;
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
static void update_cb(void);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
static stress_test_ctx_t g_ctx = { 0 };
|
||||
static const char * font_name_arr[] = {
|
||||
"./src/test_files/fonts/noto/NotoSansSC-Regular.ttf",
|
||||
"../src/libs/freetype/arial.ttf",
|
||||
"../demos/multilang/assets/fonts/Montserrat-Bold.ttf",
|
||||
"UNKNOWN_FONT_NAME"
|
||||
};
|
||||
static const uint16_t font_style[] = {
|
||||
LV_FREETYPE_FONT_STYLE_NORMAL,
|
||||
LV_FREETYPE_FONT_STYLE_ITALIC,
|
||||
LV_FREETYPE_FONT_STYLE_BOLD,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#define RND_START_SEED 0x114514
|
||||
#define CAPTURE_SKIP_FRAMES 17
|
||||
|
||||
#define MAX_FONT_SIZE 128
|
||||
#define MAX_LABEL_CNT 32
|
||||
#define MAX_LOOP_CNT 200
|
||||
#define MAX_LABEL_CONTENT_LEN 16
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static lv_obj_t * label_create(const char * font_name, lv_obj_t * par, int size, int x, int y)
|
||||
{
|
||||
uint32_t index = lv_rand(0, sizeof(font_style) / sizeof(uint16_t) - 1);
|
||||
uint32_t r = lv_rand(0, 0xFF);
|
||||
uint32_t g = lv_rand(0, 0xFF);
|
||||
uint32_t b = lv_rand(0, 0xFF);
|
||||
lv_opa_t opa = lv_rand(0, LV_OPA_COVER);
|
||||
lv_color_t color = lv_color_make(r, g, b);
|
||||
|
||||
lv_font_t * font = lv_freetype_font_create(font_name, LV_FREETYPE_FONT_RENDER_MODE_BITMAP, size, font_style[index]);
|
||||
if(!font) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_obj_t * label = lv_label_create(par);
|
||||
lv_obj_set_style_text_font(label, font, 0);
|
||||
lv_obj_set_style_text_opa(label, opa, 0);
|
||||
lv_obj_set_style_text_color(label, color, 0);
|
||||
lv_obj_set_pos(label, x, y);
|
||||
lv_obj_set_style_outline_color(label, color, 0);
|
||||
lv_obj_set_style_outline_width(label, 1, 0);
|
||||
|
||||
uint8_t str[128];
|
||||
lv_random_utf8_chars(str, sizeof(str), LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE, LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE_LEN,
|
||||
MAX_LABEL_CONTENT_LEN);
|
||||
lv_label_set_text(label, (char *)str);
|
||||
return label;
|
||||
}
|
||||
static void label_delete(lv_obj_t * label)
|
||||
{
|
||||
const lv_font_t * font = lv_obj_get_style_text_font(label, 0);
|
||||
LV_ASSERT_NULL(font);
|
||||
lv_freetype_font_delete((lv_font_t *)font);
|
||||
lv_obj_del(label);
|
||||
}
|
||||
static void label_delete_all(stress_test_ctx_t * ctx)
|
||||
{
|
||||
for(int i = 0; i < ctx->config.label_cnt; i++) {
|
||||
lv_obj_t * label = ctx->label_arr[i];
|
||||
if(label) {
|
||||
label_delete(label);
|
||||
ctx->label_arr[i] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
static void update_cb(void)
|
||||
{
|
||||
stress_test_ctx_t * ctx = &g_ctx;
|
||||
uint32_t label_index = lv_rand(0, ctx->config.label_cnt - 1);
|
||||
uint32_t font_index = lv_rand(0, ctx->config.font_cnt - 1);
|
||||
uint32_t font_size = lv_rand(0, MAX_FONT_SIZE);
|
||||
uint32_t label_x = lv_rand(0, LV_HOR_RES) - LV_HOR_RES / 2;
|
||||
uint32_t label_y = lv_rand(0, LV_VER_RES);
|
||||
|
||||
lv_obj_t * label = ctx->label_arr[label_index];
|
||||
if(label) {
|
||||
label_delete(label);
|
||||
ctx->label_arr[label_index] = NULL;
|
||||
}
|
||||
else {
|
||||
const char * pathname = ctx->config.font_name_arr[font_index];
|
||||
LV_ASSERT_NULL(pathname);
|
||||
label = label_create(
|
||||
pathname,
|
||||
ctx->par,
|
||||
(int)font_size,
|
||||
(int)label_x,
|
||||
(int)label_y);
|
||||
ctx->label_arr[label_index] = label;
|
||||
}
|
||||
}
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
lv_freetype_init(0, 0, 0);
|
||||
|
||||
g_ctx.par = lv_scr_act();
|
||||
|
||||
g_ctx.config.loop_cnt = MAX_LOOP_CNT;
|
||||
g_ctx.config.label_cnt = MAX_LABEL_CNT;
|
||||
g_ctx.config.font_name_arr = font_name_arr;
|
||||
g_ctx.config.font_cnt = sizeof(font_name_arr) / sizeof(font_name_arr[0]);
|
||||
|
||||
size_t arr_size = sizeof(lv_obj_t *) * g_ctx.config.label_cnt;
|
||||
g_ctx.label_arr = lv_malloc(arr_size);
|
||||
LV_ASSERT_MALLOC(g_ctx.label_arr);
|
||||
lv_memzero(g_ctx.label_arr, arr_size);
|
||||
|
||||
lv_rand_set_seed(RND_START_SEED);
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
label_delete_all(&g_ctx);
|
||||
lv_freetype_uninit();
|
||||
|
||||
lv_free(g_ctx.label_arr);
|
||||
}
|
||||
|
||||
void test_font_stress(void)
|
||||
{
|
||||
for(uint32_t i = 0; g_ctx.config.loop_cnt > 0; g_ctx.config.loop_cnt--) {
|
||||
update_cb();
|
||||
lv_refr_now(NULL);
|
||||
|
||||
if(g_ctx.config.loop_cnt % CAPTURE_SKIP_FRAMES == 0) {
|
||||
char buf[64];
|
||||
TEST_FREETYPE_ASSERT_EQUAL_SCREENSHOT(i);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
}
|
||||
|
||||
void test_font_stress(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
65
tests/src/test_libs/rnd_unicodes/lv_rnd_unicodes.c
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @file lv_rnd_unicodes.c
|
||||
*
|
||||
*/
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_rnd_unicodes.h"
|
||||
|
||||
|
||||
#include "rnd_unicodes/src/library.h"
|
||||
|
||||
#define UNICODE_MAX_VALUE 0x10FFFF
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
|
||||
const uint32_t LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE[] = {
|
||||
0x4e00, 0x9fa5, // CJK Unified Ideographs
|
||||
'A', 'Z',
|
||||
'a', 'z',
|
||||
'0', '9',
|
||||
};
|
||||
const uint32_t LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE_LEN = sizeof(LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE) / sizeof(
|
||||
unicode_t) / 2;
|
||||
|
||||
/**********************
|
||||
* GLOBAL VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
uint32_t RANDOM_CALL_PROCESS(void)
|
||||
{
|
||||
return lv_rand(0, UNICODE_MAX_VALUE);
|
||||
}
|
||||
|
||||
int lv_random_utf8_chars(uint8_t * buf, int buf_len, const uint32_t * ranges, uint32_t range_num, int char_num)
|
||||
{
|
||||
return random_utf8_chars(buf, buf_len, ranges, range_num, char_num);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
56
tests/src/test_libs/rnd_unicodes/lv_rnd_unicodes.h
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* @file lv_rnd_unicodes.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LV_RND_UNICODES_H
|
||||
#define LV_RND_UNICODES_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "../lvgl.h"
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
extern const uint32_t LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE[];
|
||||
extern const uint32_t LV_RND_UNICODE_ALPHANUM_AND_CJK_TABLE_LEN;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
/**
|
||||
* Generate random UTF-8 characters in the given ranges.
|
||||
* @param buf buffer to store the generated characters
|
||||
* @param buf_len length of the buffer
|
||||
* @param ranges array of ranges to choose from
|
||||
* @param range_num number of ranges
|
||||
* @param char_num number of characters to generate
|
||||
* @return number of generated characters in bytes
|
||||
*/
|
||||
int lv_random_utf8_chars(uint8_t * buf, int buf_len, const uint32_t * ranges, uint32_t range_num, int char_num);
|
||||
|
||||
/*************************
|
||||
* GLOBAL VARIABLES
|
||||
*************************/
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /*extern "C"*/
|
||||
#endif
|
||||
|
||||
#endif /*LV_RND_UNICODES_H*/
|
5
tests/src/test_libs/rnd_unicodes/rnd_unicodes/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
cmake-build-*
|
||||
build/*
|
||||
.idea
|
||||
*.o
|
||||
.DS_Store
|
@ -0,0 +1,9 @@
|
||||
cmake_minimum_required(VERSION 3.10)
|
||||
project(rnd_unicodes C)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
|
||||
add_library(rnd_unicodes SHARED src/library.c)
|
||||
|
||||
add_executable(rnd_unicodes_test examples/main.c)
|
||||
target_link_libraries(rnd_unicodes_test rnd_unicodes)
|
21
tests/src/test_libs/rnd_unicodes/rnd_unicodes/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2023 Benign X
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
41
tests/src/test_libs/rnd_unicodes/rnd_unicodes/README.md
Normal file
@ -0,0 +1,41 @@
|
||||
# rnd_unicodes
|
||||
|
||||
## Description
|
||||
|
||||
This is a simple c lib that generates a random unicode string of a given length.
|
||||
|
||||
## Usage
|
||||
|
||||
```c
|
||||
#include "library.h"
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "time.h"
|
||||
|
||||
#define BUF_LEN 1024
|
||||
|
||||
utf8_t chars[BUF_LEN];
|
||||
|
||||
// override the random function to use the system's random number generator
|
||||
uint32_t RANDOM_CALL_PROCESS(void) {
|
||||
return rand();
|
||||
}
|
||||
|
||||
int main() {
|
||||
srand(time(NULL));
|
||||
int len = random_utf8_chars(chars, BUF_LEN, ALPHANUM_AND_CJK_TABLE, ALPHANUM_AND_CJK_TABLE_LEN, 256);
|
||||
|
||||
printf("LEN: %d\n%s\n", len, chars);
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
```bash
|
||||
LEN: 398
|
||||
9Ky鰒9奷鱈39澂9R鴥8覗E祫f912QR梑dX啀凐覎liGPC俟j3S6V4ZBU8藉W舖旫iR8EFcHV8b尜橃o8Wsle121nb駆侓6璸9hQQ6Cy桪oc8姌f7X賣5孛0幬5Sb2埉w砏3XRSh钳D869b盓儊a95B菩62濆Z机郹9145UHaLT擎馇貤m臨v夛砃xPD7CWQq堾j稄3YmFw7Z欠P8PCcu7鶚68韾7KGgTN2P793L雙hy壒TGb螿虊C6m弩呚YBt0骇fAtn恔雸餙営n共1MeH嘿刑步焒簡RejV援21q77rT蛸4N橷4ZFa恲m詘焣悷b61瘥Z绢v
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
162
tests/src/test_libs/rnd_unicodes/rnd_unicodes/src/library.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Benign X
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "library.h"
|
||||
|
||||
__attribute__((weak)) uint32_t RANDOM_CALL_PROCESS(void)
|
||||
{
|
||||
/*Algorithm "xor" from p. 4 of Marsaglia, "Xorshift RNGs"*/
|
||||
static uint32_t x = 0x114514;
|
||||
x ^= x << 13;
|
||||
x ^= x >> 17;
|
||||
x ^= x << 5;
|
||||
|
||||
return x;
|
||||
}
|
||||
|
||||
const uint32_t ALPHANUM_AND_CJK_TABLE[] = {
|
||||
0x4e00, 0x9fa5, // CJK Unified Ideographs
|
||||
'A', 'Z',
|
||||
'a', 'z',
|
||||
'0', '9',
|
||||
};
|
||||
const uint32_t ALPHANUM_AND_CJK_TABLE_LEN = sizeof(ALPHANUM_AND_CJK_TABLE) / sizeof(unicode_t) / 2;
|
||||
|
||||
const uint32_t ONLY_CJK_TABLE[] = {
|
||||
0x4e00, 0x9fa5, // CJK Unified Ideographs
|
||||
};
|
||||
const uint32_t ONLY_CJK_TABLE_LEN = sizeof(ALPHANUM_AND_CJK_TABLE) / sizeof(unicode_t) / 2;
|
||||
|
||||
const uint32_t ALPHANUM_TABLE[] = {
|
||||
'A', 'Z',
|
||||
'a', 'z',
|
||||
'0', '9',
|
||||
};
|
||||
const uint32_t ALPHANUM_TABLE_LEN = sizeof(ALPHANUM_TABLE) / sizeof(unicode_t) / 2;
|
||||
|
||||
static int unicode_to_utf8_bytes_len(unicode_t unicode)
|
||||
{
|
||||
if(unicode < 0x80) {
|
||||
return 1;
|
||||
}
|
||||
else if(unicode < 0x800) {
|
||||
return 2;
|
||||
}
|
||||
else if(unicode < 0x10000) {
|
||||
return 3;
|
||||
}
|
||||
else if(unicode < 0x200000) {
|
||||
return 4;
|
||||
}
|
||||
else if(unicode < 0x4000000) {
|
||||
return 5;
|
||||
}
|
||||
else {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
static int unicode_to_uft8(utf8_t * buf, uint32_t buf_len, unicode_t unicode)
|
||||
{
|
||||
uint32_t unicode_len = unicode_to_utf8_bytes_len(unicode);
|
||||
if(buf_len < unicode_len) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int buf_index = 0;
|
||||
|
||||
switch(unicode_len) {
|
||||
case 1:
|
||||
buf[buf_index++] = (uint8_t) unicode;
|
||||
break;
|
||||
case 2:
|
||||
buf[buf_index++] = (uint8_t)(0xc0 | (unicode >> 6));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | (unicode & 0x3f));
|
||||
break;
|
||||
case 3:
|
||||
buf[buf_index++] = (uint8_t)(0xe0 | (unicode >> 12));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 6) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | (unicode & 0x3f));
|
||||
break;
|
||||
case 4:
|
||||
buf[buf_index++] = (uint8_t)(0xf0 | (unicode >> 18));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 12) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 6) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | (unicode & 0x3f));
|
||||
break;
|
||||
case 5:
|
||||
buf[buf_index++] = (uint8_t)(0xf8 | (unicode >> 24));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 18) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 12) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 6) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | (unicode & 0x3f));
|
||||
break;
|
||||
case 6:
|
||||
buf[buf_index++] = (uint8_t)(0xfc | (unicode >> 30));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 24) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 18) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 12) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | ((unicode >> 6) & 0x3f));
|
||||
buf[buf_index++] = (uint8_t)(0x80 | (unicode & 0x3f));
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return buf_index;
|
||||
}
|
||||
|
||||
static int random_one_utf8_char(utf8_t * buf, int buf_len, unicode_t char_range_min, unicode_t char_range_max)
|
||||
{
|
||||
if(buf_len < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint32_t r = RANDOM_CALL_PROCESS() % (char_range_max - char_range_min + 1) + char_range_min;
|
||||
|
||||
return unicode_to_uft8(buf, buf_len, r);
|
||||
}
|
||||
|
||||
int random_utf8_chars(utf8_t * buf, int buf_len, const unicode_t * ranges, uint32_t range_num, int char_num)
|
||||
{
|
||||
if(buf_len < char_num) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int buf_index = 0;
|
||||
for(int i = 0; i < char_num && buf_index < buf_len; i++) {
|
||||
int range_index = RANDOM_CALL_PROCESS() % range_num;
|
||||
int ret = random_one_utf8_char(buf + buf_index,
|
||||
buf_len - buf_index,
|
||||
ranges[2 * range_index],
|
||||
ranges[2 * range_index + 1]);
|
||||
if(ret < 0) {
|
||||
return -1;
|
||||
}
|
||||
buf_index += ret;
|
||||
}
|
||||
|
||||
buf[buf_index] = '\0';
|
||||
return buf_index;
|
||||
}
|
47
tests/src/test_libs/rnd_unicodes/rnd_unicodes/src/library.h
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2023 Benign X
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef RND_UNICODES_LIBRARY_H
|
||||
#define RND_UNICODES_LIBRARY_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef uint32_t unicode_t;
|
||||
typedef uint8_t utf8_t;
|
||||
|
||||
extern const uint32_t ALPHANUM_AND_CJK_TABLE[];
|
||||
extern const uint32_t ALPHANUM_AND_CJK_TABLE_LEN;
|
||||
|
||||
extern const uint32_t ONLY_CJK_TABLE[];
|
||||
extern const uint32_t ONLY_CJK_TABLE_LEN;
|
||||
|
||||
extern const uint32_t ALPHANUM_TABLE[];
|
||||
extern const uint32_t ALPHANUM_TABLE_LEN;
|
||||
|
||||
uint32_t RANDOM_CALL_PROCESS(void);
|
||||
|
||||
int random_utf8_chars(utf8_t * buf, int buf_len, const unicode_t * ranges, uint32_t range_num, int char_num);
|
||||
|
||||
#endif //RND_UNICODES_LIBRARY_H
|