首页 > 其他分享 >Office OpenXML 解析(二):字体

Office OpenXML 解析(二):字体

时间:2023-01-29 10:26:25浏览次数:68  
标签:字符 East Office 字体 Asian 解析 OpenXML eastAsia 属性

在 OpenXML 文档中,字符的字体由 RunFonts 元素指定,如下所示:

  <w:r w:rsidRPr="001B7601"> // Run
    <w:rPr>
      <w:rFonts w:hint="eastAsia" w:ascii="Times New Roman" w:hAnsi="Times New Roman" w:eastAsia="微软雅黑" w:cs="Times New Roman" /> //RunFonts
    </w:rPr>
    <w:t>中文</w:t>
  </w:r>

在一个 RunFonts 元素中,最多可以存在4种字体槽,每种字体槽可以指定一种特有的字体:

  • ASCII

  • High ANSI

  • Complex Script

  • East Asian

1. 属性

RunFonts 元素的详细属性如下:

属性 描述
ascii(ASCII Font) 指定 Unicode编码为U+0000–U+007F 范围内的字符应该使用的字体。如果同时指定了 asciiTheme 属性,那么该属性被忽略。如果未指定该属性,那么应该按照上述样式层级关系来确定它的值;如果在样式层级中均未指定,则应该使用支持该字符的默认字体。
asciiTheme (ASCII Theme Font) 指定 Unicode编码为U+0000–U+007F 范围内的字符应该使用的主题字体。该字体引用自文档主题部件的预定义 theme fonts。
cs (Complex Script Font) 指定被划分到 Complex Script 字体槽中应该使用的字体。如果同时指定了 cstheme 属性,那么该属性被忽略。如果未指定该属性,那么应该按照上述样式层级关系来确定它的值;如果在样式层级中均未指定,则应该使用支持 complex script 内容的默认字体。
cstheme (Complex Script Theme Font) 指定被划分到 Complex Script 字体槽中应该使用的主题字体。
eastAsia (East Asian Font) 指定 Unicode编码为 East Asian范围内的字符应该使用的字体。如果同时指定了 eastAsiaTheme 属性,那么该属性被忽略。如果未指定该属性,那么应该按照上述样式层级关系来确定它的值;如果在样式层级中均未指定,则应该使用支持 East Asian 内容的默认字体。
eastAsiaTheme(East Asian Theme Font) 指定 Unicode编码为 East Asian范围内的字符应该使用的主题字体。
hAnsi (High ANSI Font) 指定 Unicode编码为 High ANSI 范围内(不属于上述三类范围)的字符应该使用的字体。如果同时指定了 hAnsiTheme 属性,那么该属性被忽略。如果未指定该属性,那么应该按照上述样式层级关系来确定它的值;如果在样式层级中均未指定,则应该使用支持 High ANSI 内容的默认字体。
hAnsiTheme (High ANSI Theme Font) 指定 Unicode编码为 High ANSI 范围内(不属于上述三类范围)的字符应该使用的主题字体。
hint (Font Content Type) 指定有歧义的字符应该使用的字体类别。有些字符没有显式地存储在文档中,可以映射为上面提到的四个类别中的多个类别。这个属性就是用于解决这种冲突。例:
<w:r> <w:rPr> <w:rFonts w:ascii="Times New Roman" w:eastAsia="微软雅黑" w:hAnsi="Courier New"/> </w:rPr> <w:t>Ellipsis…</w:t> </w:r> <w:r> <w:rPr> <w:rFonts w:hint="eastAsia" w:ascii="Times New Roman" w:eastAsia="微软雅黑" w:hAnsi="Courier New"/> </w:rPr> <w:t>省略…</w:t> </w:r>
在上面两个 Run 元素中,虽然其中的省略号"…" 具有相同的 Unicode 编码(U+2026),但是由于 hint 属性的存在,它们使用的是不同的字体。

2. 两步算法(Two-step Algorithm)

第1步:查表

通过下表基于 Unicode 编码确定字符的类别:

Unicode Block 范围 类别
基本拉丁文 (Basic Latin):控制字符,标点符号,数字字母 0000-007F ASCII 字体
拉丁文补充-1 (Latin 1 Supplement) 00A0-00FF High ANSI 字体,存在以下例外:如果 hint 属性的值是 eastAsia,那么下列编码的字符使用 East Asian (或eastAsiaTheme)字体: A1, A4, A7 – A8, AA, AD, AF, B0 – B4, B6 – BA, BC – BF, D7, F7如果 hint 属性的值是 eastAsia 并且 lang(Languages)元素的eastAsia 属性值为“zh”时,下列编码的字符使用 East Asian (或eastAsiaTheme)字体: E0 – E1, E8 – EA, EC – ED, F2 –F3, F9 – FA, FC 例如,存在下面这样一个 Run 元素:<w:r> <w:rPr> <w:rFonts w:hint="eastAsia" w:ascii="Arial" w:eastAsia="微软雅黑" w:hAnsi="Times New Roman" /> <w:lang w:eastAsia="zh" /> </w:rPr> <w:t>¡¢à</w:t> </w:r> 那么,根据上述规则,第1,3个字符的字体为 “微软雅黑”,第2个字符的字体为 "Times New Roman"。
拉丁文扩展-A (Latin Extended-A) 0100-017F High ANSI 字体,存在以下例外:如果 hint 属性的值是 eastAsia 并且 lang(Languages)元素的eastAsia 属性值为“zh”,或者 East Asian 字体的字符集为 Big5 或 GB2312 时,使用 East Asian (或eastAsiaTheme)字体。
拉丁文扩展-B (Latin Extended-B) 0180-024F
国际音标扩展 (IPA Extensions) 0250-02AF
空白修饰字母 (Spacing Modifiers) 02B0-02FF 如果 hint 属性的值是 eastAsia ,那么使用 East Asian 字体,否则使用 High ANSI 字体。
结合用读音符号 (Combining Diacritics Marks) 0300-036F
希腊文 (Greek ) 0370-03CF
西里尔字母 (Cyrillic) 0400-04FF
希伯来文 (Hebrew) 0590-05FF ASCII 字体
阿拉伯文 (Arabic) 0600-06FF
叙利亚文 (Syriac) 0700-074F
阿拉伯文补充 (Arabic Supplement) 0750-077F
马尔代夫语 (Thaana) 0780-07BF
朝鲜文 (Hangul Jamo) 1100-11FF East Asian 字体
常用标点 (General Punctuation) 2000-206F 如果 hint 属性的值是 eastAsia ,那么使用 East Asian 字体,否则使用 High ANSI 字体。
CJK 部首补充 (CJK Radicals Supplement) 2E80-2EFF East Asian 字体
CJK 符号和标点 (CJK Symbols and Punctuation) 3000-303F
字母表达形式 (Alphabetic Presentation Form) FB00-FB4F FB00-FB1C:如果 hint 属性的值是 eastAsia ,那么使用 East Asian 字体,否则使用 High ANSI 字体。FB1D-FB4F:使用 ASCII 字符。

第2步

经过第1步查表之后:

如果字符被划分到了 East Asian 类别中并且 hint 属性的值是 eastAsia,那么该字符就应该使用 East Asian 字体;

否则,如果 Run 元素中存在 <w:cs/> 或者 <w:rtl/> 元素,那么字符就应该使用 Complex Script 字体,不管它的 Unicode 编码在哪个区域;

否则,使用上表中的规则。

上述的流程可以用下图来表示:

例1:下面这个 Run 元素中同时存在阿拉伯字符和英文字符,

<w:r>
    <w:rPr>
      <w:rFonts w:ascii="Courier New" w:cs="Times New Roman" />
    </w:rPr>
    <w:t>English العربية </w:t>
</w:r>

在这个 Run 元素中,指定了 ASCII 和 Complex Script 两种字体槽,根据前面的“两步”算法,我们可以得知这两种文字都会映射到 ASCII 槽中,也就是都会应用 Courier New 字体。

例2:

<w:r>
    <w:rPr>
      <w:rFonts w:ascii="Courier New" w:cs="Times New Roman" />
      <w:rtl/> // RightToLeftText
    </w:rPr>
    <w:t>English العربية </w:t>
</w:r>

在这个 Run 元素中, 同样根据下面的“两步”算法可以得知,这两种文字都会映射到 Complex Script 槽中,也就是 Times New Roman 字体。

例3:

<w:r>
    <w:rPr>
      <w:rFonts w:hint="eastAsia" />
      <w:bCs/>
      <w:rtl/>
    </w:rPr>
    <w:t>English 中文</w:t>
</w:r>

在这个例子中,“中文” 字符处于 East Asian 类别,同时 hint 属性的值为 eastAsia,所以,这两个字符应用 East Asian 字体,同时,<w:bCs/> 元素不会使其加粗。

对于“English” 字符,由于它不处于 East Asian 类别,同时又存在 <w:rtl/> 元素,那么,它应用的是 Complex Script 字体,同时,<w:bCs/> 元素会使其加粗。

所以,最终显示的时候,“English”字符会加粗,而“中文”字符不会加粗。

3. 参考

[1] ECMA-376-1:2016,Office Open XML File Formats — Fundamentals and Markup Language Reference,§17.8 Fonts

标签:字符,East,Office,字体,Asian,解析,OpenXML,eastAsia,属性
From: https://www.cnblogs.com/theyangfan/p/17071861.html

相关文章