冰糖葫芦很乖


转载来自:https://blog.csdn.net/u010727765/article/details/76852386

最近在学习chromium过程中遇到了chromium的资源,由于chromium对其资源文件进行封装的处理,比较繁琐,特此整理了一下。chromium是一个跨平台的开源项目,所以对资源进行封装的主要目的就是为了摆脱对平台的依赖。

本文主要是针对本地化字符串的翻译和使用方法。

在本人这次学习过程中,主要是针对chromium的本地化,也就是chromium支持多种语言,对于语言的翻译使用了我自己添加的语言文件,这次就是从这些翻译文件的添加和使用来介绍一下过程。

首先,需要创建2个文件:strings.grd,strings.gyp,和一个文件夹:translations/

一、grd文件

strings.grd:其格式是xml,里面使用了几个标签,如下 代码:

<?xml version="1.0" encoding="UTF-8"?>
"." current_release="1" source_lang_id="en">

"grit/strings.h" type="rc_header">

"strings_ar.pak" type="data_package" lang="ar"/>
"strings_bg.pak" type="data_package" lang="bg"/>
...


"translations/strings_ar.xtb" lang="ar" />
"translations/strings_bg.xtb" lang="bg" />
...

"1">
"true">
"IDS_XXX" desc="DESC_xxxxx">
xxxxxx

...


在以上的XML文件中,最主要的有三个节点:outputs、translations和messages

outputs:用来配置输出的文件,在将xtb文件解析后,输出到哪个文件中,这个文件名需要我们来指定,生成的文件文件就是我们在chromium需要用到的.pak文件;

translations:用来指定要翻译的各种语言的xtb文件,也就是ouputs的输入文件,xtb文件与pak文件就是一以 lang这个属性对应起来的;

messages:这个下面有一个或者多个message节点,每一个节点表示要翻译的一个字符串内容,每一个字符串有一个唯一的ID,描述,也就是以上的message name,和desc,这个有开发者来指定,必须保证是唯一的。


二、GYP文件

strings.gyp,这个文件是chromium GYP编译文件,其内容格式为json,用来指定编译的环境,其内容如下:

{
  'targets': [
    {
      'target_name': 'strings',
      'type': 'none',
      'variables': {
        'grit_out_dir': 'xxxxxxx',
      },
      'actions': [
        {
          'action_name': 'grenerate_strings',
          'variables': {
            'grit_grd_file': 'strings.grd',
          },
          'includes': [ '../../../../build/grit_action.gypi' ],
        },
      ],
      'direct_dependent_settings': {
        'includes_dirs': [
          '<(SHARED_INTERMEDIATE_DIR)',
        ],
      },
    },
  ]
}

以上文件指定了当前的一个模块名字,target_name,以及输出目录等等。

三、XTB文件

然后,在translates文件夹下面,就是我们的一系列xtb文件,文件格式为XML,以某一个语言的xtb文件为例:

<?xml version="1.0" ?>

"pt">
"xxxxxxxxxx">Menu
...

如以上文件,语言是pt,也就是葡萄牙语,translationbundle这个节点中的子节点,就是一个个需要翻译的字符串,这些都是以当前语言显示的。
在translation节点中,有一个id="xxxxxxxxxxx",这个id是由chromium中的grit工具来生成的,生成过程如下:

首先进入目录src/tools/grit/,然后运行python命令,进入python命令行,然后执行一下命令:

>>> from grit.extern.tclib import GenerateMessageId
>>> GenerateMessageId("Menu")
'3897092660631435901'
生成的一串数字就是这个Menu的Id,chromium的字符串都是以英语为基础来生成的。

四、ResourceId

到现在还不能编译,chromium会为每一个字符串生成一个唯一的Id,在字符串资源中,而这个id的生成标准是以strings.grd中的message name来生成的,这就是为什么message name要唯一的原因,字符串资源生成id的方式如下:

在src/tools/gritsettings/ 下,有一个叫做resource_ids的名字,我们在末尾指定grd文件,以及一个第一个message的id,然后grd中后续的字符串id就是从第一个id逐个加1:

"content/browser//strings/strings.grd": {
"messages": [45020],
}
从文件中能看到指定的grd文件,和起始id,这个id值必须在31000之后,31000之前都是chromium中供自己使用的。


五、生成字符串资源文件

chromium的资源文件是在编译之前就会生成的,过程如下:

1.首先会根据gyp文件,引入资源文件,主要是grd文件;

2.根据grd文件中的message节点,获取各个message的name 和 id,id由resource_ids文件中得到;

3.根据translation节点中指定的xtb文件,对每个message的翻译进行匹配,匹配的依据是上文通过字符串生成的id,如果id与字符串不匹配是不会读入的(本人犯的错);另外,chromium会以英语为默认语言,所以xtb文件中是没有lang="en-US"的文件的,否则,解析时会报错(本人犯的错);

4.在解析完成一个xtb文件时,会同时根据lang生成output中指定的pak文件。


使用语言本地化的正常流程是,chromium会进行一个系统调用getlocales来获取当前系统的语言,但是我使用的是嵌入式linux系统,没有locale支持,所以我只能使用chromium中的DataPack类来对pak文件进行读取,然后通过字符串的name来获取相应的字符串。