From 6d1f3bce07098d69432575829709c96823b0fb4e Mon Sep 17 00:00:00 2001 From: "snickersun@163.com" Date: Mon, 8 Jul 2024 14:00:20 +0000 Subject: [PATCH] Merge #481 into sdk602patch0626 from refs/changes/481/head MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 添加语言工具脚本 * refs/changes/481/head: (1 commits squashed) - 添加语言工具脚本 Signed-off-by: snickersun@163.com Reviewed-by: snickersun@163.com Merged-by: snickersun@163.com CR-link: https://codeup.aliyun.com/64191456b9581d62e8f81ac0/FD230/change/481 --- .gitignore | 1 + tools/string_packer/language_trans.py | 277 +++++++++++++++++++++++ tools/string_packer/searchdir.py | 67 ++++++ tools/string_packer/start.bat | 2 + tools/string_packer/start.sh | 1 + tools/string_packer/test/language_en.xml | 47 ++++ tools/string_packer/test/language_zh.xml | 47 ++++ 7 files changed, 442 insertions(+) create mode 100644 tools/string_packer/language_trans.py create mode 100644 tools/string_packer/searchdir.py create mode 100644 tools/string_packer/start.bat create mode 100644 tools/string_packer/start.sh create mode 100644 tools/string_packer/test/language_en.xml create mode 100644 tools/string_packer/test/language_zh.xml diff --git a/.gitignore b/.gitignore index 0004a0718..c61cb2401 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +tools/string_packer/output/** code/sdk/deveco/** code/sdk/vscode/** code/sdk/output/** diff --git a/tools/string_packer/language_trans.py b/tools/string_packer/language_trans.py new file mode 100644 index 000000000..86e6e5588 --- /dev/null +++ b/tools/string_packer/language_trans.py @@ -0,0 +1,277 @@ +#!/usr/bin/env python +# coding: utf-8 +# Description: language_trans + +import sys +sys.dont_write_bytecode = True +import xml.etree.ElementTree as ET +import zlib +import struct +import searchdir +import os + +g_lang_info = {} +g_lang_id = [] +g_lang_default_text_info = {} + +def make_sure_dir_exit(filename): + if not os.path.exists(os.path.dirname(filename)): + try: + os.makedirs(os.path.dirname(filename)) + except OSError as exc: # Guard against race condition + if exc.errno != errno.EEXIST: + raise + +class TextInfo: + KEY_VALUE = "value" + KEY_fontName = "fontName" + KEY_SIZE = "size" + KEY_DIRECT = "direct" + DIRECT_LTR = 0 + DIRECT_RTL = 1 + DIRECT_MIXED = 2 + DIRECT_NONE = 3 + + def __init__(self, info): + self._info = info + + def get_size(self): + if TextInfo.KEY_SIZE in self._info: + return int(self._info[TextInfo.KEY_SIZE]) + else: + return 0 + + def get_font_name(self): + if TextInfo.KEY_fontName in self._info: + return self._info[TextInfo.KEY_fontName] + return None + + def get_value(self): + if TextInfo.KEY_VALUE in self._info: + return self._info[TextInfo.KEY_VALUE] + return "" + + def get_direct(self): + if TextInfo.KEY_DIRECT in self._info: + if self._info[TextInfo.KEY_DIRECT] == "ltr": + return TextInfo.DIRECT_LTR + if self._info[TextInfo.KEY_DIRECT] == "rtl": + return TextInfo.DIRECT_RTL + if self._info[TextInfo.KEY_DIRECT] == "mixed": + return TextInfo.DIRECT_MIXED + return TextInfo.DIRECT_NONE + + def __repr__(self): + return "%s" % (self._info) + + +def int_prim_xml_layer_tree(tree): + root = tree.getroot() + layer_root_element = ET.Element('') + for child_1 in root: + if child_1.tag == 'language': + layer_root_element = child_1 + break + return layer_root_element + + +def get_lang_binary_body(tree): + offset = b'' + str = b'' + num = b'' + crcData = b'' + langId = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + # print(len(tree.findall('lanstr'))) + num += len(tree.findall('lanstr')).to_bytes(4, byteorder="little") + for item in tree.findall('lanstr'): + id = item.get('id') + value = item.get('value') + str += bytes(value, 'utf-8') + str += b'\x00' + offset += (len(bytes(value, 'utf-8')) + + 1).to_bytes(4, byteorder="little") + + langId = struct.pack('16s', bytes(tree.get('languageinfo'), 'utf-8')) + crcData += zlib.crc32(langId + num + offset + + str).to_bytes(4, byteorder="little") + return crcData + langId + num + offset + str + + +def get_lang_head_body(tree): + result = '' + index = 0 + result += '/*\r\n' + result += '* Copyright (c) xxxxxxxx Technologies Co., Ltd. 2021-2021. All rights reserved.\r\n' + result += '* Description: language\r\n' + result += '* Author: Graphic develop team\r\n' + result += '* Create: 2021-07-06\r\n' + result += '*/\r\n' + result += '\r\n' + result += '#ifndef UI_TEXT_LANGUAGE_H\r\n' + result += '#define UI_TEXT_LANGUAGE_H\r\n' + result += '#include \r\n' + result += 'namespace OHOS {\r\n' + result += 'enum UITextLanguageTextId : uint16_t {\r\n' + + for item in tree.findall('lanstr'): + id = item.get('id') + value = item.get('value') + result += ' ' + id + ' = ' + str(index) + ',\r\n' + index += 1 + result += '}; // UITextLanguageTextId\r\n' + result += '#endif /* UI_TEXT_LANGUAGE_H */\r\n' + return result + + +def get_lang_binary_body_map(map, langType): + # print(langType) + offset = b'' + str = b'' + num = b'' + crcData = b'' + langId = b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' + # print(len(tree.findall('lanstr'))) + keys = map.keys() + totalNum = len(keys) + index = 0 + default_text_info = g_lang_default_text_info[langType] + # check default fontName + default_fontName = default_text_info.get_font_name() + if default_fontName != None: + str += bytes(default_fontName, 'utf-8') + str += b'\x00' + index += len(bytes(default_fontName, 'utf-8')) + 1 + totalNum |= 0x8000 + num += totalNum.to_bytes(2, byteorder="little") + + for item in keys: + id = item + if langType in map[item]: + text_info = map[item][langType] + else: + text_info = TextInfo({}) + value = text_info.get_value() + str += bytes(value, 'utf-8') + str += b'\x00' + index_value = index + font_size = text_info.get_size() + if font_size > 0: + index_value |= (index_value & 0xFF000000) | (font_size << 24) + + direct = text_info.get_direct() + if direct == TextInfo.DIRECT_NONE: + direct = default_text_info.get_direct() + if direct != None: + index_value |= (index_value & 0x00600000) | (direct << 21) + + font_name = text_info.get_font_name() + if font_name != None: + index_value |= (index_value | 0x00800000) + str += bytes(font_name, 'utf-8') + str += b'\x00' + index += len(bytes(font_name, 'utf-8')) + 1 + + offset += (index_value).to_bytes(4, byteorder="little") + index += len(bytes(value, 'utf-8')) + 1 + + langId = struct.pack('16s', bytes(langType, 'utf-8')) + crcData += zlib.crc32(langId + num + offset + + str).to_bytes(4, byteorder="little") + return crcData + langId + num + offset + str + + +def GetTextInfo(item): + info = {} + if item.get(TextInfo.KEY_VALUE) != None: + info[TextInfo.KEY_VALUE] = item.get(TextInfo.KEY_VALUE) + if item.get(TextInfo.KEY_SIZE) != None: + info[TextInfo.KEY_SIZE] = item.get(TextInfo.KEY_SIZE) + if item.get(TextInfo.KEY_fontName) != None: + info[TextInfo.KEY_fontName] = item.get(TextInfo.KEY_fontName) + if item.get(TextInfo.KEY_DIRECT) != None: + info[TextInfo.KEY_DIRECT] = item.get(TextInfo.KEY_DIRECT) + text_info = TextInfo(info) + return text_info + + +def get_lang_map(tree): + langid = tree.get('languageinfo') + g_lang_id.append(langid) + # print(g_lang_id) + + text_info = GetTextInfo(tree) + # print(text_info) + g_lang_default_text_info[langid] = text_info + + for item in tree.findall('lanstr'): + text_info = GetTextInfo(item) + id = item.get('id') + value = item.get('value') + if id in g_lang_info: + g_lang_info[id][langid] = text_info + else: + g_lang_info[id] = {langid: text_info} + # print(g_lang_info) + + +def get_language_id_enum(): + result = """ +enum FontLanguageId : uint8_t { +""" + for language in g_lang_id: + result += " LANGUAGE_ID_" + language.upper() + ",\r\n" + result += ' LANGUAGE_ID_MAX\r\n' + result += '}; // UITextLanguageTextId\r\n' + return result + + +def get_lang_head_body_map(map): + result = """/* +* Copyright (c) xxxxxxxx Technologies Co., Ltd. 2021-2021. All rights reserved. +* Description: language +* Author: Graphic develop team +* Create: 2021-07-06 +*/ + +#ifndef UI_RESOURCE_STRING_H +#define UI_RESOURCE_STRING_H +#include +namespace OHOS { +enum UIResourceTextId : uint16_t { +""" + index = 0 + keys = map.keys() + for item in keys: + id = item + result += ' ' + id + ' = ' + str(index) + ',\r\n' + index += 1 + result += ' ' + "STR_MAX_ID" + ' = ' + str(index) + ',\r\n' + result += '}; // UIResourceTextId\r\n' + result += get_language_id_enum() + result += '}\r\n' + result += '#endif /* UI_RESOURCE_STRING_H */\r\n' + # print(result) + return result + + +if __name__ == "__main__": + args = len(sys.argv) + argv = sys.argv + if (args < 3): + print("param should be \'xmlpath langPath headPath\'") + # sys.exit() + dirlist = searchdir.BASE() + dirlist.RecusWalkDir(dir=argv[1]) + for item in dirlist.fileList: + # print(item) + tree = ET.parse(item).getroot() + get_lang_map(tree) + for item in g_lang_id: + bin = get_lang_binary_body_map(g_lang_info, item) + make_sure_dir_exit(os.path.join(argv[2], item + ".lang")); + with open(os.path.join(argv[2], item + ".lang"), 'wb+') as file: + file.write(bin) + head = get_lang_head_body_map(g_lang_info) + make_sure_dir_exit(os.path.join(argv[3], "ui_resource_string.h")) + with open(os.path.join(argv[3], "ui_resource_string.h"), 'wb+') as file: + file.write(bytes(head, 'utf-8')) diff --git a/tools/string_packer/searchdir.py b/tools/string_packer/searchdir.py new file mode 100644 index 000000000..3ae824459 --- /dev/null +++ b/tools/string_packer/searchdir.py @@ -0,0 +1,67 @@ +import os + +#全局变量设置歌曲预定格式 +Const_Song_Format=["xml"] + + +class BASE: + #类变量,设置文件列表 + fileList=[] + #类变量,设置文件计算 + counter=0 + def __init__(self): + pass + def RecusWalkDir(self,dir,filtrate=0): + """本方法递归遍历目的文件夹中所有文件,获取指定格式的文件绝对地址,利用类变量fileList存储地址""" + global Const_Song_Format + for s in os.listdir(dir): + newDir=dir+"/"+s + if os.path.isdir(newDir): + self.RecusWalkDir(newDir) + else: + if os.path.isfile(newDir): + + if newDir and (self.GetFileFormat(newDir) in Const_Song_Format): + self.__class__.fileList.append(newDir) + self.__class__.counter+=1 + + + + def CycWalkDir(self,dir,filtrate=0): + """本方法循环遍历文件夹中所有文件,获取指定格式的文件绝对地址,返回歌曲列表fileList""" + global Const_Song_Format + fileList=[""] + for s in os.listdir(dir): + newDir=dir+"/"+s + if os.path.isfile(newDir): + if filtrate: + if newDir and (self.GetFileFormat(newDir) in Const_Song_Format): + fileList.append(newDir) + else: + fileList.append(newDir) + else: + newDir=dir+"/"+s + while os.path.isdir(newDir): + for s in os.listdir(dir): + newDir=dir+"/"+s + if os.path.isfile(newDir): + if filtrate: + if newDir and (self.GetFileFormat(newDir) in Const_Song_Format): + fileList.append(newDir) + else: + fileList.append(newDir) + else: + newDir=dir+"/"+s + return fileList + + + def GetFileFormat(self,fileName): + """返回文件格式""" + if fileName: + BaseName=os.path.basename(fileName) + str=BaseName.split(".") + + return str[-1] + else: + return fileName + diff --git a/tools/string_packer/start.bat b/tools/string_packer/start.bat new file mode 100644 index 000000000..3f30b4277 --- /dev/null +++ b/tools/string_packer/start.bat @@ -0,0 +1,2 @@ +python language_trans.py .\test .\output .\output +pause \ No newline at end of file diff --git a/tools/string_packer/start.sh b/tools/string_packer/start.sh new file mode 100644 index 000000000..55d3c49ad --- /dev/null +++ b/tools/string_packer/start.sh @@ -0,0 +1 @@ +python language_trans.py test output output diff --git a/tools/string_packer/test/language_en.xml b/tools/string_packer/test/language_en.xml new file mode 100644 index 000000000..cd18d8552 --- /dev/null +++ b/tools/string_packer/test/language_en.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + diff --git a/tools/string_packer/test/language_zh.xml b/tools/string_packer/test/language_zh.xml new file mode 100644 index 000000000..915c525af --- /dev/null +++ b/tools/string_packer/test/language_zh.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + -- 2.17.1