From 3989c6e82447c9d16d0ea61948eecdcdcf24a68b Mon Sep 17 00:00:00 2001 From: lixianjing Date: Thu, 2 Jan 2025 16:35:41 +0800 Subject: [PATCH] improve tools and build scripts --- docs/changes.md | 1 + scripts/update_res_app.py | 6 +- scripts/update_res_common.py | 273 ++++++++++++++++++++--------- tools/common/utils.c | 205 +++++++++++++++++++++- tools/common/utils.h | 7 + tools/image_gen/main.c | 103 ++++++++++- tools/res_gen/main.c | 110 +++++++++++- tools/svg_gen/bsvg_gen.cc | 105 ++++++++++- tools/theme_gen/main.cc | 109 +++++++++++- tools/ui_gen/xml_to_ui/xml_to_ui.c | 115 +++++++++++- 10 files changed, 910 insertions(+), 124 deletions(-) diff --git a/docs/changes.md b/docs/changes.md index b21f531513..ea5bef7221 100644 --- a/docs/changes.md +++ b/docs/changes.md @@ -2,6 +2,7 @@ 2025/01/02 * 去掉重复的宏定义(感谢俊杰发现问题) + * 完善打包工具和脚本,各工具新增src_filename参数,可根据文件内的资源文件数组打包指定的资源(感谢培煌提供补丁) 2025/01/01 * 完善 freertos 移植。 diff --git a/scripts/update_res_app.py b/scripts/update_res_app.py index 4057cb32c1..47a0cc7033 100755 --- a/scripts/update_res_app.py +++ b/scripts/update_res_app.py @@ -34,7 +34,7 @@ def use_theme_config_from_res_config(res_config_path, config = None): if not os.path.exists(config_json) : print(config_json + ' is not exists.') return - + content = res_config.res_config() content.load_file(config_json) else : @@ -68,7 +68,7 @@ def use_theme_config_from_res_config(res_config_path, config = None): else: imagegen_options = 'rgba' - if IS_GENERATE_INC_BITMAP: + if IS_GENERATE_INC_BITMAP and not content.get_storage_dir(): config_dir = common.join_path(ASSETS_ROOT, common.join_path(theme_name, 'fonts/config')) common.remove_dir(config_dir) common.make_dirs(config_dir) @@ -242,7 +242,7 @@ def run(awtk_root, is_excluded_file_handler = None, is_new_usage = False) : print('For details, please read scripts/README.md.') else: if GDPI != '': - DPI = GDPI + DPI = GDPI if IMAGEGEN_OPTIONS != '': for theme in THEMES : theme["imagegen_options"] = IMAGEGEN_OPTIONS diff --git a/scripts/update_res_common.py b/scripts/update_res_common.py index f4cde813ce..f7c5def761 100755 --- a/scripts/update_res_common.py +++ b/scripts/update_res_common.py @@ -8,6 +8,8 @@ import shutil import platform import subprocess +import fnmatch +import json ########################### DPI = 'x1' @@ -382,12 +384,12 @@ def exec_cmd(cmd): sys.exit(1) -def themegen(raw, inc, theme): - exec_cmd('\"' + to_exe('themegen') + '\" \"' + raw + '\" \"' + inc + '\" data ' + theme) +def themegen(raw, inc, theme, sources_file = ' '): + exec_cmd('\"' + to_exe('themegen') + '\" \"' + raw + '\" \"' + inc + '\" \"' + sources_file + '\" data ' + theme) -def themegen_bin(raw, bin): - exec_cmd('\"' + to_exe('themegen') + '\" \"' + raw + '\" \"' + bin + '\" bin') +def themegen_bin(raw, bin, sources_file = ' '): + exec_cmd('\"' + to_exe('themegen') + '\" \"' + raw + '\" \"' + bin + '\" \"' + sources_file + '\" bin') def strgen(raw, inc, theme): @@ -397,8 +399,8 @@ def strgen(raw, inc, theme): def strgen_bin(raw, bin): exec_cmd('\"' + to_exe('strgen') + '\" \"' + raw + '\" \"' + bin + '\" bin') -def resgen(raw, inc, theme, outExtname): - exec_cmd('\"' + to_exe('resgen') + '\" \"' + raw + '\" \"' + inc + '\" ' + theme + ' ' + outExtname) +def resgen(raw, inc, theme, outExtname, sources_file = ' '): + exec_cmd('\"' + to_exe('resgen') + '\" \"' + raw + '\" \"' + inc + '\" \"' + sources_file + '\" ' + theme + ' ' + outExtname) def fontgen(raw, text, inc, size, options, theme): @@ -410,26 +412,26 @@ def fontgen(raw, text, inc, size, options, theme): str(size) + ' ' + options + ' ' + theme) -def imagegen(raw, inc, options, theme, lcd_orientation, lcd_fast_rotation_mode): +def imagegen(raw, inc, options, theme, lcd_orientation, lcd_fast_rotation_mode, sources_file = ' '): if not lcd_fast_rotation_mode : lcd_orientation = '0' - exec_cmd('\"' + to_exe('imagegen') + '\" \"' + raw + '\" \"' + inc + '\" ' + options + ' ' + theme + ' ' + lcd_orientation) + exec_cmd('\"' + to_exe('imagegen') + '\" \"' + raw + '\" \"' + inc + '\" ' + options + ' \"' + sources_file + '\" ' + theme + ' ' + lcd_orientation) -def svggen(raw, inc, theme): - exec_cmd('\"' + to_exe('bsvggen') + '\" \"' + raw + '\" \"' + inc + '\" data ' + theme) +def svggen(raw, inc, theme, sources_file = ' '): + exec_cmd('\"' + to_exe('bsvggen') + '\" \"' + raw + '\" \"' + inc + '\" \"' + sources_file + '\" data ' + theme) -def svggen_bin(raw, bin): - exec_cmd('\"' + to_exe('bsvggen') + '\" \"' + raw + '\" \"' + bin + '\" bin') +def svggen_bin(raw, bin, sources_file = ' '): + exec_cmd('\"' + to_exe('bsvggen') + '\" \"' + raw + '\" \"' + bin + '\" \"' + sources_file + '\" bin') -def xml_to_ui(raw, inc, theme): - exec_cmd('\"' + to_exe('xml_to_ui') + '\" \"' + raw + '\" \"' + inc + '\" data \"\" ' + theme) +def xml_to_ui(raw, inc, theme, sources_file = ' '): + exec_cmd('\"' + to_exe('xml_to_ui') + '\" \"' + raw + '\" \"' + inc + '\" \"' + sources_file + '\" data \"\" ' + theme) -def xml_to_ui_bin(raw, bin): - exec_cmd('\"' + to_exe('xml_to_ui') + '\" \"' + raw + '\" \"' + bin + '\" bin') +def xml_to_ui_bin(raw, bin, sources_file = ' '): + exec_cmd('\"' + to_exe('xml_to_ui') + '\" \"' + raw + '\" \"' + bin + '\" \"' + sources_file + '\" bin') def gen_res_all_style(): @@ -442,15 +444,19 @@ def gen_res_all_style(): emit_generate_res_before('style') + sources_file = ' ' + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/styles.json') + if IS_GENERATE_RAW: bin = join_path(OUTPUT_DIR, 'raw/styles') make_dirs(bin) - themegen_bin(raw, bin) + themegen_bin(raw, bin, sources_file) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc = join_path(OUTPUT_DIR, 'inc/styles') make_dirs(inc) - themegen(raw, inc, THEME) + themegen(raw, inc, THEME, sources_file) emit_generate_res_after('style') @@ -460,40 +466,62 @@ def gen_res_svg(): if not os.path.exists(raw): return + sources_file = ' ' + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/images.json') + if IS_GENERATE_RAW: bin = join_path(OUTPUT_DIR, 'raw/images/svg') make_dirs(bin) - svggen_bin(raw, bin) + svggen_bin(raw, bin, sources_file) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc = join_path(OUTPUT_DIR, 'inc/images') make_dirs(inc) - svggen(raw, inc, THEME) + svggen(raw, inc, THEME, sources_file) def gen_res_png_jpg(): if IS_GENERATE_RAW: if INPUT_DIR != join_path(OUTPUT_DIR, 'raw'): - dirs = ['xx', 'x1', 'x2', 'x3', 'x4'] - for d in dirs: - raw = join_path(INPUT_DIR, 'images/'+d) - if os.path.exists(raw): - dst = join_path(OUTPUT_DIR, 'raw/images/'+d) - if os.path.exists(dst): - remove_dir(dst) - copy_dir(raw, dst) + names = None + in_folder = join_path(INPUT_DIR, 'images/') + out_folder = in_folder.replace(INPUT_DIR, join_path(OUTPUT_DIR, 'raw')) + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/images.json') + names = get_res_names_from_sources_file(sources_file) + if isinstance(names, list): + for name in names: + if name.startswith('svg/'): + continue + in_file = join_path(in_folder, name) + out_file = join_path(out_folder, name) + make_dirs(os.path.dirname(out_file)) + copy_file(in_file, out_file) + else: + dirs = ['xx', 'x1', 'x2', 'x3', 'x4'] + for d in dirs: + raw = join_path(INPUT_DIR, 'images/'+d) + if os.path.exists(raw): + dst = join_path(OUTPUT_DIR, 'raw/images/'+d) + if os.path.exists(dst): + remove_dir(dst) + copy_dir(raw, dst) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc = join_path(OUTPUT_DIR, 'inc/images') dirs = [DPI, 'xx'] + sources_file = ' ' + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/images.json') for d in dirs: raw = join_path(INPUT_DIR, 'images/'+d) if os.path.exists(raw): make_dirs(inc) if IS_GENERATE_INC_RES: - resgen(raw, inc, THEME, '.res') + resgen(raw, inc, THEME, '.res', sources_file) if IS_GENERATE_INC_BITMAP: - imagegen(raw, inc, IMAGEGEN_OPTIONS, THEME, LCD_ORIENTATION, LCD_FAST_ROTATION_MODE) + imagegen(raw, inc, IMAGEGEN_OPTIONS, THEME, LCD_ORIENTATION, LCD_FAST_ROTATION_MODE, sources_file) # 如果当前主题的gen选项与default主题不一致,则按新的gen选项重新生成图片的位图数据 if IS_GENERATE_INC_BITMAP and THEME != 'default': @@ -506,7 +534,7 @@ def gen_res_png_jpg(): if os.path.exists(raw): make_dirs(inc) - imagegen(raw, inc, IMAGEGEN_OPTIONS, THEME, LCD_ORIENTATION, LCD_FAST_ROTATION_MODE) + imagegen(raw, inc, IMAGEGEN_OPTIONS, THEME, LCD_ORIENTATION, LCD_FAST_ROTATION_MODE, sources_file) def gen_res_all_image(): @@ -518,7 +546,6 @@ def gen_res_all_image(): gen_res_svg() emit_generate_res_after('image') - def gen_res_all_ui(): if not THEME_PACKAGED and THEME != 'default': return @@ -529,15 +556,19 @@ def gen_res_all_ui(): emit_generate_res_before('ui') + sources_file = ' ' + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/ui.json') + if IS_GENERATE_RAW: bin = join_path(OUTPUT_DIR, 'raw/ui') make_dirs(bin) - xml_to_ui_bin(raw, bin) + xml_to_ui_bin(raw, bin, sources_file) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc = join_path(OUTPUT_DIR, 'inc/ui') make_dirs(inc) - xml_to_ui(raw, inc, THEME) + xml_to_ui(raw, inc, THEME, sources_file) emit_generate_res_after('ui') @@ -552,17 +583,30 @@ def gen_res_all_data(): emit_generate_res_before('data') + sources_file = ' ' + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/data.json') + if IS_GENERATE_RAW: if INPUT_DIR != join_path(OUTPUT_DIR, 'raw'): - dst = join_path(OUTPUT_DIR, 'raw/data') - if os.path.exists(dst): - remove_dir(dst) - copy_dir(raw, dst) + in_folder = join_path(INPUT_DIR, 'data') + out_folder = join_path(OUTPUT_DIR, 'raw/data') + if sources_file != ' ': + names = get_res_names_from_sources_file(sources_file) + for name in names: + in_file = join_path(in_folder, name) + out_file = join_path(out_folder, name) + make_dirs(os.path.dirname(out_file)) + copy_file(in_file, out_file) + else: + if os.path.exists(out_folder): + remove_dir(out_folder) + copy_dir(raw, out_folder) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc = join_path(OUTPUT_DIR, 'inc/data') make_dirs(inc) - resgen(raw, inc, THEME, '.data') + resgen(raw, inc, THEME, '.data', sources_file) emit_generate_res_after('data') @@ -617,25 +661,39 @@ def gen_res_all_xml(): def gen_res_bitmap_font(input_dir, font_options, theme): + storage_dir = input_dir if STORAGE_DIR: - input_dir = join_path(STORAGE_DIR, theme) + storage_dir = join_path(STORAGE_DIR, theme) - if not os.path.exists(join_path(input_dir, 'fonts/config')): + if not os.path.exists(join_path(storage_dir, 'fonts/config')): return - for f in glob.glob(join_path(input_dir, 'fonts/config/*.txt')): + font_names = None + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/fonts.json') + font_names = get_res_names_from_sources_file(sources_file) + if font_names: + font_names = list(map(lambda s: os.path.splitext(s)[0], font_names)) + + for f in glob.glob(join_path(storage_dir, 'fonts/config/*.txt')): filename, extname = os.path.splitext(f) fontname = os.path.basename(filename) + index = fontname.rfind('_') if index > 0: - raw = join_path(input_dir, 'fonts') + '/origin/' + fontname[0: index] + '.ttf' + size = fontname[index + 1 : len(fontname)] + fontname = fontname[0: index] + + if font_names and fontname not in font_names: #有指定资源,但当前字体不在指定资源内,则跳过 + continue + + raw = join_path(storage_dir, 'fonts') + '/origin/' + fontname + '.ttf' if not os.path.exists(raw): - raw = os.path.dirname(os.path.dirname(filename)) + '/' + fontname[0: index] + '.ttf' - if os.path.exists(raw): - size = fontname[index + 1 : len(fontname)] - if size.isdigit(): - inc = join_path(OUTPUT_DIR, 'inc/fonts/' + fontname[0: index] + '_' + str(size) + '.data') - fontgen(raw, f, inc, size, font_options, theme) + raw = join_path(input_dir, 'fonts') + '/' + fontname + '.ttf' + + if os.path.exists(raw) and size.isdigit(): + inc = join_path(OUTPUT_DIR, 'inc/fonts/' + fontname + '_' + str(size) + '.data') + fontgen(raw, f, inc, size, font_options, theme) def gen_res_all_font(): @@ -643,20 +701,33 @@ def gen_res_all_font(): return emit_generate_res_before('font') + font_files = None + if STORAGE_DIR: + sources_file = join_path(STORAGE_DIR, THEME + '/fonts.json') + names = get_res_names_from_sources_file(sources_file) + if isinstance(names, list): + font_files = list(map(lambda n: join_path(join_path(INPUT_DIR, 'fonts/'), n), names)) if IS_GENERATE_RAW: if INPUT_DIR != join_path(OUTPUT_DIR, 'raw'): make_dirs(join_path(OUTPUT_DIR, 'raw/fonts')) - - in_files = join_path(INPUT_DIR, 'fonts/') - for f in get_appint_folder(in_files, '.ttf', False): - out_files = f[0].replace(INPUT_DIR, join_path(OUTPUT_DIR, 'raw')) - out_foler = os.path.dirname(out_files) - if 'origin' in out_foler: - continue - if not os.path.exists(out_foler): - make_dirs(out_foler) - copy_file(f[0], out_files) + in_folder = join_path(INPUT_DIR, 'fonts/') + if isinstance(font_files, list): + for in_file in font_files: + out_file = in_file.replace(INPUT_DIR, join_path(OUTPUT_DIR, 'raw')) + out_folder = os.path.dirname(out_file) + if not os.path.exists(out_folder): + make_dirs(out_folder) + copy_file(in_file, out_file) + else: + for f in get_appint_folder(in_folder, '.ttf', False): + out_files = f[0].replace(INPUT_DIR, join_path(OUTPUT_DIR, 'raw')) + out_folder = os.path.dirname(out_files) + if 'origin' in out_folder: + continue + if not os.path.exists(out_folder): + make_dirs(out_folder) + copy_file(f[0], out_files) if IS_GENERATE_INC_RES or IS_GENERATE_INC_BITMAP: inc_dir = join_path(OUTPUT_DIR, 'inc/fonts') @@ -693,18 +764,28 @@ def gen_res_all_font(): fontgen(raw, text, inc, size, font_options, THEME) if IS_GENERATE_INC_RES: - if not os.path.exists(join_path(INPUT_DIR, 'fonts')): + in_folder = join_path(INPUT_DIR, 'fonts') + if not os.path.exists(in_folder): return - for f in get_appint_folder(join_path(INPUT_DIR, 'fonts/'), ".ttf", False): - filename, extname = os.path.splitext(f[0]) - raw = f[0] - filename = filename.replace(INPUT_DIR, join_path(OUTPUT_DIR, 'inc')) - inc = filename + '.res' - if "origin" in inc: - continue - resgen(raw, inc, THEME, '.res') - + if isinstance(font_files, list): + for in_file in font_files: + filename, extname = os.path.splitext(in_file) + out_file = filename.replace(INPUT_DIR, join_path(OUTPUT_DIR, 'inc')) + out_file = out_file + '.res' + out_folder = os.path.dirname(out_file) + if not os.path.exists(out_folder): + make_dirs(out_folder) + resgen(in_file, out_file, THEME, '.res') + else: + for f in get_appint_folder(in_folder, ".ttf", False): + filename, extname = os.path.splitext(f[0]) + raw = f[0] + filename = filename.replace(INPUT_DIR, join_path(OUTPUT_DIR, 'inc')) + inc = filename + '.res' + if "origin" in inc: + continue + resgen(raw, inc, THEME, '.res') emit_generate_res_after('font') @@ -1228,38 +1309,38 @@ def get_opts(args) : 'res_config_script_argv=', 'RES_CONFIG_SCRIPT_ARGV=', 'output_dir=', 'OUTPUT_DIR=', 'app_root=', 'APP_ROOT', - ]; + ] try : - opts, tmp_args = getopt.getopt(args, 'h', longsots); - return opts; + opts, tmp_args = getopt.getopt(args, 'h', longsots) + return opts except getopt.GetoptError as err: - print(err.msg); - return None; + print(err.msg) + return None def is_all_sopts_args(args) : for arg in args: if not arg.startswith('--') and not arg.startswith('-'): - return False; - return True; + return False + return True def get_longsopt_name_by_tuple(tuple) : - return tuple[0][2:].lower(); + return tuple[0][2:].lower() def get_shortopt_name_by_tuple(tuple) : - return tuple[0][1:].lower(); + return tuple[0][1:].lower() def get_longsopts_args(args) : - opts = get_opts(args); + opts = get_opts(args) if opts != None : - data = {}; + data = {} for tmp_opts in opts : value = tmp_opts[1] if isinstance(value, str) and value[0] == '"' and value[-1] == '"' : value = value[1:-1] data[get_longsopt_name_by_tuple(tmp_opts)] = value - return data; + return data else : - return None; + return None def show_usage_imlp(is_new_usage): if is_new_usage : @@ -1340,19 +1421,19 @@ def show_usage(is_new_usage = False): if len(sys.argv) == 1: show_usage_imlp(is_new_usage) else: - args = sys.argv[1:]; + args = sys.argv[1:] if is_all_sopts_args(args) : - opts = get_opts(args); + opts = get_opts(args) if opts == None : show_usage_imlp(is_new_usage) else : - find_action = False; + find_action = False for tmp_opts in opts : - str_opt = get_longsopt_name_by_tuple(tmp_opts); + str_opt = get_longsopt_name_by_tuple(tmp_opts) if str_opt == 'help' or get_shortopt_name_by_tuple(tmp_opts) == 'h': show_usage_imlp(is_new_usage) elif str_opt == 'action' : - find_action = True; + find_action = True if not find_action : show_usage_imlp(is_new_usage) else : @@ -1360,3 +1441,21 @@ def show_usage(is_new_usage = False): if len(sys_args) == 0 : show_usage_imlp(is_new_usage) +def find_ttf_files(folder): + ttf_files = [] + for root, dirs, files in os.walk(folder): + t_files = fnmatch.filter(files, '*.ttf') + for filename in t_files: + ttf_files.append(os.path.join(root, filename)) + return ttf_files + +def get_res_names_from_sources_file(sources_file): + try: + with open(sources_file, 'r', encoding='utf-8') as file: + data = json.load(file) + if 'sources' in data: + return data['sources'] + return [] + except (FileNotFoundError, json.JSONDecodeError) as e: + print('An error occurred: {}'.format(e)) + return None diff --git a/tools/common/utils.c b/tools/common/utils.c index d1208c3d2f..a5170a90d3 100644 --- a/tools/common/utils.c +++ b/tools/common/utils.c @@ -26,12 +26,18 @@ #include #include #include + #include "tkc/fs.h" #include "tkc/mem.h" #include "tkc/wstr.h" -#include "base/enums.h" #include "tkc/path.h" +#include "tkc/str.h" +#include "tkc/data_reader_factory.h" +#include "tkc/data_reader_file.h" +#include "base/enums.h" #include "base/assets_manager.h" +#include "conf_io/conf_json.h" +#include "utils.h" static bool_t exit_if_need_not_update_for_include_subfile(const char* in, fs_stat_info_t* fst_out) { fs_stat_info_t fst_in; @@ -190,10 +196,31 @@ int unique(wchar_t* str, int size) { return d - str; } +static str_t* format_folder_name(const char* name) { + str_t* str = str_create(2 * TK_NAME_LEN + 1); + + tokenizer_t t; + tokenizer_init(&t, name, strlen(name), "/\\"); + while (tokenizer_has_more(&t)) { + const char* text = tokenizer_next(&t); + if(str->size == 0) { + str_set(str, text); + } else { + str_append(str, "_"); // 目录名称前再加一个 "_",避免文件重名冲突。 + str_append(str, text); + } + str_append(str, "_"); // 将斜杠替换为 "_" + } + tokenizer_deinit(&t); + + str_pop(str); // 去掉末尾多余的"_" + return str; +} + static const char* to_var_name(char var_name[2 * TK_NAME_LEN + 1], const char* theme, const char* prefix, const char* name) { char tmp[TK_NAME_LEN + 1] = {0}; - char tmp_var_name[2 * TK_NAME_LEN + 1]; + char tmp_var_name[2 * TK_NAME_LEN + 1] = {0}; const char* p = name + tk_strlen(name); while (p != name) { if (*p == '\\' || *p == '/') { @@ -361,3 +388,177 @@ const char* filter_name(char* name) { return name; } + +ret_t ensure_output_res_name(str_t* str_name, bool_t is_bin, const char* ext) { + return_value_if_fail(str_name != NULL, RET_BAD_PARAMS); + + if (!is_bin) { + char basename[MAX_PATH] = {0}; + char dirname[MAX_PATH] = {0}; + + path_basename(str_name->str, basename, MAX_PATH); + if (!tk_str_eq(str_name->str, basename)) { + path_dirname(str_name->str, dirname, MAX_PATH); + str_set(str_name, dirname); + str_append(str_name, "/"); + str_append(str_name, filter_name(basename)); + } else { + str_set(str_name, filter_name(basename)); + } + } + + str_append(str_name, ext); + + return RET_OK; +} + +ret_t makesure_folder_exist(const char* folder) { + char tmp[MAX_PATH + 1] = {0}; + if (end_with(folder, "\\") || end_with(folder, "/")) { + tk_strncpy(tmp, folder, tk_strlen(folder) - 1); + folder = tmp; + } + + char p_folder[MAX_PATH + 1] = {0}; + path_dirname(folder, p_folder, MAX_PATH); + if (!fs_dir_exist(os_fs(), p_folder)) { + makesure_folder_exist(p_folder); + } + + if (!fs_dir_exist(os_fs(), folder)) { + fs_create_dir(os_fs(), folder); + } + + return RET_OK; +} + +darray_t* get_res_names_from_sources_file(const char* src_filename, darray_t* sources) { + data_reader_factory_t* factory = data_reader_factory(); + if (factory == NULL) { + data_reader_factory_set(data_reader_factory_create()); + data_reader_factory_register(data_reader_factory(), "file", data_reader_file_create); + } + + tk_object_t* json = conf_json_load(src_filename, FALSE); + if (json != NULL) { + char propname[MAX_PATH] = {0}; + int32_t size = tk_object_get_prop_int(json, "sources.#size", -1); + if (size > 0) { + for (int32_t i = 0; i < size; i++) { + memset(propname, 0x00, sizeof(propname)); + tk_snprintf(propname, sizeof(propname), "sources.[%d]", i); + + const char* item = tk_object_get_prop_str(json, propname); + char* name = tk_str_copy(NULL, item); + darray_push(sources, name); + } + } + } + + return sources; +} + +darray_t* get_image_names_from_sources_file(const char* src_filename, darray_t* sources, + const char* dpr) { + data_reader_factory_t* factory = data_reader_factory(); + if (factory == NULL) { + data_reader_factory_set(data_reader_factory_create()); + data_reader_factory_register(data_reader_factory(), "file", data_reader_file_create); + } + + tk_object_t* json = conf_json_load(src_filename, FALSE); + + char propname[MAX_PATH] = {0}; + int32_t size = tk_object_get_prop_int(json, "sources.#size", -1); + if (size > 0) { + for (int32_t i = 0; i < size; i++) { + memset(propname, 0x00, sizeof(propname)); + tk_snprintf(propname, sizeof(propname), "sources.[%d]", i); + + const char* item = tk_object_get_prop_str(json, propname); + if (tk_str_start_with(item, dpr)) { + char* file = tk_str_copy(NULL, item + strlen(dpr) + 1); + darray_push(sources, file); + } + } + } + + return sources; +} + +darray_t* get_res_names_from_sources_file_bak(const char* src_filename, darray_t* sources, + const char* theme, const char* type) { + data_reader_factory_t* factory = data_reader_factory(); + if (factory == NULL) { + data_reader_factory_set(data_reader_factory_create()); + data_reader_factory_register(data_reader_factory(), "file", data_reader_file_create); + } + + tk_object_t* json = conf_json_load(src_filename, FALSE); + + char type_prop[128] = {0}; + tk_snprintf(type_prop, sizeof(type_prop), "sources.%s.%s", theme, type); + char propname[MAX_PATH] = {0}; + tk_snprintf(propname, sizeof(propname), "%s.#size", type_prop); + + int32_t size = tk_object_get_prop_int(json, propname, -1); + if (size > 0) { + for (int32_t i = 0; i < size; i++) { + memset(propname, 0x00, sizeof(propname)); + tk_snprintf(propname, sizeof(propname), "%s.[%d]", type_prop, i); + + const char* item = tk_object_get_prop_str(json, propname); + char* file = tk_str_copy(NULL, item); + darray_push(sources, file); + } + } + + return sources; +} + +darray_t* get_image_names_from_sources_file_bak(const char* src_filename, darray_t* sources, + const char* theme, const char* dpr) { + data_reader_factory_t* factory = data_reader_factory(); + if (factory == NULL) { + data_reader_factory_set(data_reader_factory_create()); + data_reader_factory_register(data_reader_factory(), "file", data_reader_file_create); + } + + tk_object_t* json = conf_json_load(src_filename, FALSE); + + char type_prop[128] = {0}; + tk_snprintf(type_prop, sizeof(type_prop), "sources.%s.%s", theme, "images"); + char propname[MAX_PATH] = {0}; + tk_snprintf(propname, sizeof(propname), "%s.#size", type_prop); + + int32_t size = tk_object_get_prop_int(json, propname, -1); + if (size > 0) { + for (int32_t i = 0; i < size; i++) { + memset(propname, 0x00, sizeof(propname)); + tk_snprintf(propname, sizeof(propname), "%s.[%d]", type_prop, i); + + const char* item = tk_object_get_prop_str(json, propname); + if (tk_str_start_with(item, dpr)) { + char* file = tk_str_copy(NULL, item + strlen(dpr) + 1); + darray_push(sources, file); + } + } + } + + return sources; +} + +char* get_image_dpr(const char* folder) { + char dpr_names[5][4] = {"xx", "x1", "x2", "x3", "x4"}; + char basename[MAX_PATH] = {0}; + path_basename(folder, basename, MAX_PATH); + + for (int32_t i = 0; i < 5; i++) { + if (tk_str_eq(basename, dpr_names[i])) { + char* dpr = TKMEM_ZALLOCN(char, 4); + return tk_str_copy(dpr, basename); + } + } + + return NULL; +} \ No newline at end of file diff --git a/tools/common/utils.h b/tools/common/utils.h index 9cc9ffe94d..59611b80c1 100644 --- a/tools/common/utils.h +++ b/tools/common/utils.h @@ -24,6 +24,7 @@ #include "tkc/str.h" #include "tkc/utils.h" +#include "tkc/darray.h" BEGIN_C_DECLS @@ -53,6 +54,12 @@ bool_t case_end_with(const char* p, const char* str); const char* get_next_token(const char* p, char* token, char c); const char* filter_name(char* name); +ret_t makesure_folder_exist(const char* folder); +darray_t* get_res_names_from_sources_file(const char* src_filename, darray_t* sources); +darray_t* get_image_names_from_sources_file(const char* src_filename, darray_t* sources, + const char* dpr); +char* get_image_dpr(const char* folder); +ret_t ensure_output_res_name(str_t* str_name, bool_t is_bin, const char* ext); END_C_DECLS diff --git a/tools/image_gen/main.c b/tools/image_gen/main.c index a5adcb59c1..47f47b68c6 100644 --- a/tools/image_gen/main.c +++ b/tools/image_gen/main.c @@ -22,6 +22,7 @@ #include "tkc/fs.h" #include "tkc/path.h" #include "tkc/mem.h" +#include "tkc/tokenizer.h" #include "image_gen.h" #include "common/utils.h" #include "base/image_manager.h" @@ -140,10 +141,87 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, c return RET_OK; } +static ret_t gen_sources(const char* src_filename, const char* in_foldername, + const char* out_foldername, const char* theme, const char* dir_name, + image_format_t* image_format, lcd_orientation_t o) { + fs_item_t item; + ret_t ret = RET_OK; + char in_name[MAX_PATH] = {0}; + char out_name[MAX_PATH] = {0}; + fs_dir_t* dir = fs_open_dir(os_fs(), in_foldername); + + if (!fs_file_exist(os_fs(), src_filename)) { + log_debug("gen fail, sources file \"%s\" not exist!", src_filename); + return RET_FAIL; + } + + if (!fs_dir_exist(os_fs(), out_foldername)) { + fs_create_dir(os_fs(), out_foldername); + } + + darray_t sources; + darray_init(&sources, 10, default_destroy, NULL); + + char type[63] = {0}; + path_basename(out_foldername, type, sizeof(type)); + const char* dpr = get_image_dpr(in_foldername); + if (dpr) { + get_image_names_from_sources_file(src_filename, &sources, dpr); + TKMEM_FREE(dpr); + } else { + get_res_names_from_sources_file(src_filename, &sources); + } + + for (size_t i = 0; i < sources.size; i++) { + str_t str_name; + str_t res_name; + char ext_array[MAX_PATH] = {0}; + const char* name = (const char*)darray_get(&sources, i); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + if (!fs_file_exist(os_fs(), in_name)) { + continue; + } + + const char* p = strrchr(name, '.'); + path_extname(name, ext_array, MAX_PATH); + + str_init(&res_name, 0); + str_init(&str_name, 0); + str_set(&str_name, name); + str_replace(&str_name, ext_array, ""); + ensure_output_res_name(&str_name, FALSE, ".data"); + + str_append(&res_name, dir_name); + str_append(&res_name, name); + str_replace(&res_name, p, ""); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + path_build(out_name, MAX_PATH, out_foldername, str_name.str, NULL); + + char out_folder[MAX_PATH + 1] = {0}; + path_dirname(out_name, out_folder, MAX_PATH); + makesure_folder_exist(out_folder); + + ret = gen_one(in_name, out_name, theme, res_name.str, image_format, o); + str_reset(&str_name); + str_reset(&res_name); + if (ret != RET_OK) { + break; + } + } + + darray_deinit(&sources); + + return ret; +} + int wmain(int argc, wchar_t* argv[]) { const char* in_filename = NULL; const char* out_filename = NULL; + const char* src_filename = NULL; const wchar_t* format = NULL; + const char* sources = NULL; lcd_orientation_t lcd_orientation = LCD_ORIENTATION_0; platform_prepare(); @@ -160,17 +238,27 @@ int wmain(int argc, wchar_t* argv[]) { image_format_t image_format = {BITMAP_FMT_RGBA8888, BITMAP_FMT_RGBA8888}; image_format_set(&image_format, format); - str_t theme_name; - str_init(&theme_name, 0); + str_t src_file; + str_init(&src_file, 0); if (argc > 4) { - str_from_wstr(&theme_name, argv[4]); + str_from_wstr(&src_file, argv[4]); + str_trim(&src_file, " "); + if (!str_eq(&src_file, "")) { + src_filename = src_file.str; + } } + str_t theme_name; + str_init(&theme_name, 0); if (argc > 5) { + str_from_wstr(&theme_name, argv[5]); + } + + if (argc > 6) { wstr_t str_lcd_orientation; int tmp_lcd_orientation = 0; wstr_init(&str_lcd_orientation, 0); - wstr_append(&str_lcd_orientation, argv[5]); + wstr_append(&str_lcd_orientation, argv[6]); if (wstr_to_int(&str_lcd_orientation, &tmp_lcd_orientation) == RET_OK) { lcd_orientation = (lcd_orientation_t)tmp_lcd_orientation; } @@ -194,7 +282,12 @@ int wmain(int argc, wchar_t* argv[]) { fs_stat(os_fs(), in_filename, &in_stat_info); fs_stat(os_fs(), out_filename, &out_stat_info); if (in_stat_info.is_dir == TRUE && out_stat_info.is_dir == TRUE) { - gen_folder(in_filename, out_filename, theme_name.str, "", &image_format, lcd_orientation); + if (src_filename != NULL) { + gen_sources(src_filename, in_filename, out_filename, theme_name.str, "", &image_format, + lcd_orientation); + } else { + gen_folder(in_filename, out_filename, theme_name.str, "", &image_format, lcd_orientation); + } } else if (in_stat_info.is_reg_file == TRUE) { char name[MAX_PATH + 1] = {0}; path_basename_ex(in_filename, TRUE, name, sizeof(name)); diff --git a/tools/res_gen/main.c b/tools/res_gen/main.c index b236104350..4a6ae46fbc 100644 --- a/tools/res_gen/main.c +++ b/tools/res_gen/main.c @@ -21,6 +21,7 @@ #include "tkc/fs.h" #include "tkc/path.h" #include "tkc/mem.h" +#include "tkc/tokenizer.h" #include "common/utils.h" #include "base/assets_manager.h" static ret_t gen_one(const char* in_filename, const char* out_filename, const char* theme, @@ -168,24 +169,104 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, c return ret; } + +static ret_t gen_sources(const char* src_filename, const char* in_foldername, + const char* out_foldername, const char* theme, const char* extname, + const char* dir_name, bool_t data_folder) { + fs_item_t item; + ret_t ret = RET_OK; + char in_name[MAX_PATH] = {0}; + char out_name[MAX_PATH] = {0}; + + if (!fs_file_exist(os_fs(), src_filename)) { + log_debug("gen fail, sources file \"%s\" not exist!", src_filename); + return RET_FAIL; + } + + if (!fs_dir_exist(os_fs(), out_foldername)) { + fs_create_dir(os_fs(), out_foldername); + } + + darray_t sources; + darray_init(&sources, 0, default_destroy, NULL); + + char type[63] = {0}; + path_basename(out_foldername, type, sizeof(type)); + const char* dpr = get_image_dpr(in_foldername); + if (dpr) { + get_image_names_from_sources_file(src_filename, &sources, dpr); + TKMEM_FREE(dpr); + } else { + get_res_names_from_sources_file(src_filename, &sources); + } + + for (size_t i = 0; i < sources.size; i++) { + str_t str_name; + str_t res_name; + char ext_array[MAX_PATH] = {0}; + const char* name = (const char*)darray_get(&sources, i); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + if (!fs_file_exist(os_fs(), in_name)) { + continue; + } + path_extname(name, ext_array, MAX_PATH); + + str_init(&res_name, 0); + str_init(&str_name, 0); + str_set(&str_name, name); + if (!data_folder) { + str_replace(&str_name, ext_array, ""); + } + ensure_output_res_name(&str_name, FALSE, extname); + + str_append(&res_name, dir_name); + str_append(&res_name, name); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + path_build(out_name, MAX_PATH, out_foldername, str_name.str, NULL); + + char out_folder[MAX_PATH + 1] = {0}; + path_dirname(out_name, out_folder, MAX_PATH); + makesure_folder_exist(out_folder); + + ret = gen_one(in_name, out_name, theme, &res_name); + str_reset(&str_name); + str_reset(&res_name); + if (ret == RET_FAIL) { + printf( + "gen fail, filename = %s! desc = the resource file is empty, please confirm that the " + "resource file has saved data.!\n", + in_name); + break; + } + } + + darray_deinit(&sources); + return ret; +} + bool_t is_data_folder(const char* folder_name) { char basename[MAX_PATH] = {0}; path_basename(folder_name, basename, MAX_PATH); return tk_str_eq(basename, "data"); } + int wmain(int argc, wchar_t* argv[]) { const char* in_filename = NULL; const char* out_filename = NULL; + const char* src_filename = NULL; platform_prepare(); if (argc < 3) { - printf("Usage: %S in_filename out_filename [theme] [out_extname]\n", argv[0]); + printf("Usage: %S in_filename out_filename [src_filename] [theme] [out_extname]\n", argv[0]); return 0; } str_t in_file; str_t out_file; + str_t src_file; str_t str_extname; str_t theme_name; @@ -195,13 +276,22 @@ int wmain(int argc, wchar_t* argv[]) { str_from_wstr(&in_file, argv[1]); str_from_wstr(&out_file, argv[2]); - str_init(&theme_name, 0); + str_init(&src_file, 0); if (argc > 3) { - str_from_wstr(&theme_name, argv[3]); + str_from_wstr(&src_file, argv[3]); + str_trim(&src_file, " "); + if (!str_eq(&src_file, "")) { + src_filename = src_file.str; + } } - str_init(&str_extname, 0); + + str_init(&theme_name, 0); if (argc > 4) { - str_from_wstr(&str_extname, argv[4]); + str_from_wstr(&theme_name, argv[4]); + } + str_init(&str_extname, 0); + if (argc > 5) { + str_from_wstr(&str_extname, argv[5]); } in_filename = in_file.str; @@ -212,8 +302,13 @@ int wmain(int argc, wchar_t* argv[]) { fs_stat(os_fs(), in_filename, &in_stat_info); fs_stat(os_fs(), out_filename, &out_stat_info); if (in_stat_info.is_dir == TRUE && out_stat_info.is_dir == TRUE) { - gen_folder(in_filename, out_filename, theme_name.str, str_extname.str, "", - is_data_folder(in_filename)); + if (src_filename != NULL) { + gen_sources(src_filename, in_filename, out_filename, theme_name.str, str_extname.str, "", + is_data_folder(in_filename)); + } else { + gen_folder(in_filename, out_filename, theme_name.str, str_extname.str, "", + is_data_folder(in_filename)); + } } else if (in_stat_info.is_reg_file == TRUE) { str_t res_name; char name[MAX_PATH + 1] = {0}; @@ -233,6 +328,7 @@ int wmain(int argc, wchar_t* argv[]) { str_reset(&in_file); str_reset(&out_file); + str_reset(&src_file); str_reset(&theme_name); str_reset(&str_extname); diff --git a/tools/svg_gen/bsvg_gen.cc b/tools/svg_gen/bsvg_gen.cc index 0fb9fa8534..a32744d288 100644 --- a/tools/svg_gen/bsvg_gen.cc +++ b/tools/svg_gen/bsvg_gen.cc @@ -22,6 +22,7 @@ #include "tkc/mem.h" #include "tkc/fs.h" #include "tkc/path.h" +#include "tkc/tokenizer.h" #include "common/utils.h" #include "base/assets_manager.h" #include "svg/svg_to_bsvg.h" @@ -118,34 +119,122 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, c return ret; } +static ret_t gen_sources(const char* src_filename, const char* in_foldername, + const char* out_foldername, const char* theme, const char* dir_name, + bool_t bin) { + fs_item_t item; + ret_t ret = RET_OK; + char in_name[MAX_PATH] = {0}; + char out_name[MAX_PATH] = {0}; + fs_dir_t* dir = fs_open_dir(os_fs(), in_foldername); + + if (!fs_file_exist(os_fs(), src_filename)) { + log_debug("gen fail, sources file \"%s\" not exist!", src_filename); + return RET_FAIL; + } + + if (!fs_dir_exist(os_fs(), out_foldername)) { + fs_create_dir(os_fs(), out_foldername); + } + + darray_t sources; + darray_init(&sources, 10, default_destroy, NULL); + + char type[63] = {0}; + path_basename(in_foldername, type, sizeof(type)); + get_image_names_from_sources_file(src_filename, &sources, "svg"); + + for (size_t i = 0; i < sources.size; i++) { + str_t str_name; + str_t res_name; + char ext_array[MAX_PATH] = {0}; + const char* name = (const char*)darray_get(&sources, i); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + if (!fs_file_exist(os_fs(), in_name)) { + continue; + } + + path_extname(name, ext_array, MAX_PATH); + str_init(&res_name, 0); + str_init(&str_name, 0); + str_set(&str_name, name); + str_replace(&str_name, ext_array, ""); + ensure_output_res_name(&str_name, bin, ".bsvg"); + + str_append(&res_name, dir_name); + str_append(&res_name, name); + str_replace(&res_name, ".svg", ""); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + path_build(out_name, MAX_PATH, out_foldername, str_name.str, NULL); + + char out_folder[MAX_PATH + 1] = {0}; + path_dirname(out_name, out_folder, MAX_PATH); + makesure_folder_exist(out_folder); + + ret = gen_one(in_name, out_name, theme, res_name.str, bin); + str_reset(&str_name); + str_reset(&res_name); + if (ret != RET_OK) { + break; + } + } + + darray_deinit(&sources); + return ret; +} + int wmain(int argc, wchar_t* argv[]) { - bool_t output_bin = argc == 4; + bool_t output_bin = FALSE; const char* in_filename = NULL; const char* out_filename = NULL; + const char* src_filename = NULL; + const char* output_type = NULL; platform_prepare(); if (argc < 3) { - printf("Usage: %S svg_filename bsvg_filename [bin]\n", argv[0]); + printf("Usage: %S svg_filename bsvg_filename [src_filename] [bin]\n", argv[0]); return 0; } str_t in_file; str_t out_file; + str_t src_file; str_t theme_name; + str_t _output_type; str_init(&in_file, 0); str_init(&out_file, 0); str_from_wstr(&in_file, argv[1]); str_from_wstr(&out_file, argv[2]); - in_filename = in_file.str; out_filename = out_file.str; - str_init(&theme_name, 0); + str_init(&src_file, 0); + if (argc > 3) { + str_from_wstr(&src_file, argv[3]); + str_trim(&src_file, " "); + if (!str_eq(&src_file, "")) { + src_filename = src_file.str; + } + } + + str_init(&_output_type, 0); if (argc > 4) { - str_from_wstr(&theme_name, argv[4]); + str_from_wstr(&_output_type, argv[4]); + str_trim(&_output_type, " "); + output_type = _output_type.str; + if (tk_str_eq(output_type, "bin")) { + output_bin = TRUE; + } + } + + str_init(&theme_name, 0); + if (argc > 5) { + str_from_wstr(&theme_name, argv[5]); } fs_stat_info_t in_stat_info; @@ -153,7 +242,11 @@ int wmain(int argc, wchar_t* argv[]) { fs_stat(os_fs(), in_filename, &in_stat_info); fs_stat(os_fs(), out_filename, &out_stat_info); if (in_stat_info.is_dir == TRUE && out_stat_info.is_dir == TRUE) { - gen_folder(in_filename, out_filename, theme_name.str, "", output_bin); + if (src_filename != NULL) { + gen_sources(src_filename, in_filename, out_filename, theme_name.str, "", output_bin); + } else { + gen_folder(in_filename, out_filename, theme_name.str, "", output_bin); + } } else if (in_stat_info.is_reg_file == TRUE) { char name[MAX_PATH + 1] = {0}; path_basename_ex(in_filename, TRUE, name, sizeof(name)); diff --git a/tools/theme_gen/main.cc b/tools/theme_gen/main.cc index ba7e2fec9e..e918cf45ce 100644 --- a/tools/theme_gen/main.cc +++ b/tools/theme_gen/main.cc @@ -21,6 +21,7 @@ #include "tkc/fs.h" #include "tkc/path.h" #include "tkc/mem.h" +#include "tkc/tokenizer.h" #include "common/utils.h" #include "xml_theme_gen.h" @@ -36,6 +37,75 @@ ret_t gen_one(const char* input_file, const char* output_file, const char* theme return ret; } +static ret_t gen_sources(const char* src_filename, const char* in_foldername, + const char* out_foldername, const char* theme, const char* dir_name, + bool_t output_bin) { + fs_item_t item; + ret_t ret = RET_OK; + const char* c_xml = ".xml"; + char in_name[MAX_PATH] = {0}; + char out_name[MAX_PATH] = {0}; + + if (!fs_file_exist(os_fs(), src_filename)) { + log_debug("gen fail, sources file \"%s\" not exist!", src_filename); + return RET_FAIL; + } + + if (!fs_dir_exist(os_fs(), out_foldername)) { + fs_create_dir(os_fs(), out_foldername); + } + + darray_t sources; + darray_init(&sources, 10, default_destroy, NULL); + + char type[63] = {0}; + path_basename(in_foldername, type, sizeof(type)); + get_res_names_from_sources_file(src_filename, &sources); + + for (size_t i = 0; i < sources.size; i++) { + str_t str_name; + str_t res_name; + char ext_array[MAX_PATH] = {0}; + const char* name = (const char*)darray_get(&sources, i); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + if (!fs_file_exist(os_fs(), in_name)) { + continue; + } + + path_extname(name, ext_array, MAX_PATH); + + str_init(&res_name, 0); + str_init(&str_name, 0); + str_set(&str_name, name); + str_replace(&str_name, ext_array, ""); + ensure_output_res_name(&str_name, output_bin, output_bin ? ".bin" : ".data"); + + str_append(&res_name, dir_name); + str_append(&res_name, name); + str_replace(&res_name, ".xml", ""); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + path_build(out_name, MAX_PATH, out_foldername, str_name.str, NULL); + + char out_folder[MAX_PATH + 1] = {0}; + path_dirname(out_name, out_folder, MAX_PATH); + makesure_folder_exist(out_folder); + + ret = gen_one(in_name, out_name, theme, res_name.str, output_bin); + str_reset(&str_name); + str_reset(&res_name); + + if (ret == RET_FAIL) { + GEN_ERROR(in_name); + break; + } + } + + darray_deinit(&sources); + return ret; +} + static ret_t gen_folder(const char* in_foldername, const char* out_foldername, const char* theme, const char* dir_name, bool_t output_bin) { fs_item_t item; @@ -98,20 +168,24 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, c } int wmain(int argc, wchar_t* argv[]) { - bool_t output_bin = argc == 4; + bool_t output_bin = FALSE; const char* in_filename = NULL; const char* out_filename = NULL; + const char* src_filename = NULL; + const char* output_type = NULL; platform_prepare(); if (argc < 3) { - printf("Usage: %S input output [bin] [theme]\n", argv[0]); + printf("Usage: %S input output [src_filename] [bin] [theme]\n", argv[0]); return 0; } str_t in_file; str_t out_file; + str_t src_file; str_t theme_name; + str_t _output_type; str_init(&in_file, 0); str_init(&out_file, 0); @@ -121,9 +195,28 @@ int wmain(int argc, wchar_t* argv[]) { in_filename = in_file.str; out_filename = out_file.str; + str_init(&src_file, 0); + if (argc > 3) { + str_from_wstr(&src_file, argv[3]); + str_trim(&src_file, " "); + if (!str_eq(&src_file, "")) { + src_filename = src_file.str; + } + } + + str_init(&_output_type, 0); + if(argc > 4) { + str_from_wstr(&_output_type, argv[4]); + str_trim(&_output_type, " "); + output_type = _output_type.str; + if(tk_str_eq(output_type, "bin")) { + output_bin = TRUE; + } + } + str_init(&theme_name, 0); - if (argc > 4) { - str_from_wstr(&theme_name, argv[4]); + if (argc > 5) { + str_from_wstr(&theme_name, argv[5]); } fs_stat_info_t in_stat_info; @@ -131,7 +224,11 @@ int wmain(int argc, wchar_t* argv[]) { fs_stat(os_fs(), in_filename, &in_stat_info); fs_stat(os_fs(), out_filename, &out_stat_info); if (in_stat_info.is_dir == TRUE && out_stat_info.is_dir == TRUE) { - gen_folder(in_filename, out_filename, theme_name.str, "", output_bin); + if (src_filename != NULL) { + gen_sources(src_filename, in_filename, out_filename, theme_name.str, "", output_bin); + } else { + gen_folder(in_filename, out_filename, theme_name.str, "", output_bin); + } } else if (in_stat_info.is_reg_file == TRUE) { char name[MAX_PATH + 1] = {0}; path_basename_ex(in_filename, TRUE, name, sizeof(name)); @@ -142,7 +239,9 @@ int wmain(int argc, wchar_t* argv[]) { str_reset(&in_file); str_reset(&out_file); + str_reset(&src_file); str_reset(&theme_name); + str_reset(&_output_type); return 0; } diff --git a/tools/ui_gen/xml_to_ui/xml_to_ui.c b/tools/ui_gen/xml_to_ui/xml_to_ui.c index 992cf37d33..353be321a8 100644 --- a/tools/ui_gen/xml_to_ui/xml_to_ui.c +++ b/tools/ui_gen/xml_to_ui/xml_to_ui.c @@ -20,8 +20,10 @@ */ #include "tkc/fs.h" -#include "tkc/path.h" #include "tkc/mem.h" +#include "tkc/path.h" +#include "tkc/darray.h" +#include "tkc/tokenizer.h" #include "common/utils.h" #include "base/assets_manager.h" #include "ui_loader/ui_binary_writer.h" @@ -112,7 +114,6 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, b GEN_ERROR(in_name); break; } - } else if (item.is_dir && !tk_str_eq(item.name, ".") && !tk_str_eq(item.name, "..")) { char sub_in_folder[MAX_PATH] = {0}; char sub_out_folder[MAX_PATH] = {0}; @@ -138,23 +139,94 @@ static ret_t gen_folder(const char* in_foldername, const char* out_foldername, b return ret; } +static ret_t gen_sources(const char* src_filename, const char* in_foldername, + const char* out_foldername, bool_t output_bin, const char* res_name, + const char* theme_name) { + fs_item_t item; + ret_t ret = RET_OK; + const char* c_xml = ".xml"; + char in_name[MAX_PATH] = {0}; + char out_name[MAX_PATH] = {0}; + + if (!fs_file_exist(os_fs(), src_filename)) { + log_debug("gen fail, sources file \"%s\" not exist!", src_filename); + return RET_FAIL; + } + + if (!fs_dir_exist(os_fs(), out_foldername)) { + fs_create_dir(os_fs(), out_foldername); + } + + darray_t sources; + darray_init(&sources, 10, default_destroy, NULL); + get_res_names_from_sources_file(src_filename, &sources); + + for (size_t i = 0; i < sources.size; i++) { + str_t str_name; + str_t sub_res_name; + char ext_array[MAX_PATH] = {0}; + const char* name = (const char*)darray_get(&sources, i); + + path_build(in_name, MAX_PATH, in_foldername, name, NULL); + if (!fs_file_exist(os_fs(), in_name)) { + continue; + } + + path_extname(name, ext_array, MAX_PATH); + + str_init(&sub_res_name, 0); + if (res_name != NULL) { + str_set(&sub_res_name, res_name); + } + + str_init(&str_name, 0); + str_set(&str_name, name); + str_replace(&str_name, ext_array, ""); + str_append(&sub_res_name, str_name.str); + ensure_output_res_name(&str_name, output_bin, output_bin ? ".bin" : ".data"); + path_build(out_name, MAX_PATH, out_foldername, str_name.str, NULL); + + char out_folder[MAX_PATH + 1] = {0}; + path_dirname(out_name, out_folder, MAX_PATH); + makesure_folder_exist(out_folder); + + ret = gen_one(in_name, out_name, output_bin, sub_res_name.str, theme_name); + str_reset(&str_name); + str_reset(&sub_res_name); + + if (ret == RET_FAIL) { + GEN_ERROR(in_name); + break; + } + } + + darray_deinit(&sources); + + return ret; +} + int wmain(int argc, wchar_t* argv[]) { - bool_t output_bin = argc == 4; + bool_t output_bin = FALSE; const char* in_filename = NULL; const char* out_filename = NULL; + const char* src_filename = NULL; + const char* output_type = NULL; const char* res_name = NULL; const char* theme_name = NULL; platform_prepare(); if (argc < 3) { - printf("Usage: %S in_filename out_filename [bin] [res_name] [theme]\n", argv[0]); + printf("Usage: %S in_filename out_filename [src_filename] [bin] [res_name] [theme] \n", argv[0]); return 0; } str_t in_file; str_t out_file; + str_t src_file; + + str_t _output_type; str_t _res_name; str_t str_theme; @@ -172,21 +244,44 @@ int wmain(int argc, wchar_t* argv[]) { fs_stat(os_fs(), in_filename, &in_stat_info); fs_stat(os_fs(), out_filename, &out_stat_info); + str_init(&src_file, 0); + if (argc > 3) { + str_from_wstr(&src_file, argv[3]); + str_trim(&src_file, " "); + if (!str_eq(&src_file, "")) { + src_filename = src_file.str; + } + } + + str_init(&_output_type, 0); + if (argc > 4) { + str_from_wstr(&_output_type, argv[4]); + str_trim(&_output_type, " "); + output_type = _output_type.str; + if (tk_str_eq(output_type, "bin")) { + output_bin = TRUE; + } + } + str_init(&_res_name, 0); - if (argc > 4) { //custom output res name - str_from_wstr(&_res_name, argv[4]); + if (argc > 5) { //custom output res name + str_from_wstr(&_res_name, argv[5]); str_trim(&_res_name, " "); res_name = _res_name.str; } str_init(&str_theme, 0); - if (argc > 5) { // theme - str_from_wstr(&str_theme, argv[5]); + if (argc > 6) { // theme + str_from_wstr(&str_theme, argv[6]); theme_name = str_theme.str; } if (in_stat_info.is_dir == TRUE && out_stat_info.is_dir == TRUE) { - gen_folder(in_filename, out_filename, output_bin, res_name, theme_name); + if (src_filename != NULL) { + gen_sources(src_filename, in_filename, out_filename, output_bin, res_name, theme_name); + } else { + gen_folder(in_filename, out_filename, output_bin, res_name, theme_name); + } } else if (in_stat_info.is_reg_file == TRUE) { if (gen_one(in_filename, out_filename, output_bin, res_name, theme_name) == RET_FAIL) { GEN_ERROR(in_filename); @@ -197,8 +292,10 @@ int wmain(int argc, wchar_t* argv[]) { str_reset(&in_file); str_reset(&out_file); + str_reset(&src_file); str_reset(&_res_name); str_reset(&str_theme); + str_reset(&_output_type); return 0; }