Skip to content

Latest commit

 

History

History
executable file
·
262 lines (216 loc) · 11.9 KB

HOW_TO_MAKE_JP.md

File metadata and controls

executable file
·
262 lines (216 loc) · 11.9 KB

pinyin font 作り方

要件

拼音を表示する対象は16026個ある。

ベースにしたフォント

宋体

source-han-serif(思源宋体) otf から、不要な文字を取り除いた Source-Han-TrueType をベースにしている。
拼音部分には M+ M Type-1 の mplus-1m-medium.ttf を利用している。

手書き風

シャオライ/Xiaolai Font をベースにしている。これはグリフ数削減のためにハングル文字(a960 #ꥠ ~ d7fb #ퟻ) を除去して使っている。
拼音部分には 瀬戸フォント を利用している。

依存関係の解消

otfcc

otfcc は軽量で IVS にも対応している。

jq

jq は、json から少ない労力で値抽出・集計・整形して表示したりできるコマンドです。

mac only

# Xcode をインストールしておく
$ mas install 497799835
# Xcode は最初は [Command line Tools:] リストボックスが空欄になっているため、error になってしまう。
# 以下の対処をすると直る。
# [エラー:xcode-select: error: tool 'xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is a command line tools instance](https://qiita.com/eytyet/items/59c5bad1c167d5addc68)

$ brew tap caryll/tap 
$ brew install otfcc-mac64

python

$ pyenv global 3.8.2
$ pip install -r requirements.txt

生成手順

  1. 多音字の辞書を作る(省略可能)
    詳細へ
$ cd <PROJECT-ROOT>/res/phonics/duo_yin_zi/scripts/
$ python make_pattern_table.py
  1. 対象の漢字の unicode テーブルを作る(省略可能)
    詳細へ
$ cd <PROJECT-ROOT>/res/phonics/unicode_mapping_table/
$ python make_unicode_pinyin_map_table.py 
  1. ビルドする
$ cd <PROJECT ROOT>
$ time python src/main.py --style han_serif

or

$ time python src/main.py --style handwritten

技術的メモ

pinyin表示部のサイズ設定方法

outline

    METADATA_FOR_PINYIN = {
        "pinyin_canvas":{
            "width"    : 850,   # 拼音表示部の幅
            "height"   : 283.3, # 拼音表示部の高さ
            "base_line": 935,   # ベースラインからの高さ
            "tracking" : 22.145 # 拼音の標準空白幅: Tracking is about uniform spacing across a text selection.
        },
        "expected_hanzi_canvas":{
            "width" : 1000, # 基準にする漢字の表示部の幅
            "height": 1000, # 基準にする漢字の表示部の高さ
        }
    }

refer to pinyin_glyph.py, config.py

グリフのコンポーネント化

グリフはコンポーネント化して参照することができる。 再利用によって容量を減らすことができ、アフィン変換で配置するのでサイズ・位置を簡単に設定できる。

参照の利用例:

"cid48219": {
  "advanceWidth": 2048,
  "advanceHeight": 2628.2,
  "verticalOrigin": 1803,
  "references": [
    {
      "glyph": "arranged_ji1", "x": 0, "y": 0, "a": 1, "b": 0, "c": 0, "d": 1
    },
    {
      "glyph": "cid48219.ss00", "x": 0, "y": 0, "a": 1, "b": 0, "c": 0, "d": 1
    }
  ]
},

Apple-The 'glyf' table

The transformation entries determine the values of an affine transformation applied to the component prior to its being incorporated into the parent glyph. Given the component matrix [a b c d e f], the transformation applied to the component is:

参照時に指定している a-d は、アフィン変換の値である。 今回は、「拡大縮小」と「平行移動」を使うので、a,d (scale) と x,y (move) を指定して使っている。

$$\begin{align*} \begin{pmatrix} x' \\\ y' \\\ \end{pmatrix} = \begin{pmatrix} a & c & e \\\ b & d & f \\\ \end{pmatrix} \begin{pmatrix} x \\\ y \\\ 1 \\\ \end{pmatrix} \end{align*}$$

注意:otfccbuild の仕様なのか opentype の仕様なのか分からないが a と d が同じ値だと、グリフが消失する。 少しでもサイズが違えば反映されるので、90% にするなら、a=0.9, d=0.91 とかにする。
refer to pinyin_glyph.py

feature tag

aalt は代替文字の表示のために設定している。
aalt_0 は gsub_single. 拼音が一つのみの漢字 + 記号とか。置き換え対象が一つのみのとき aalt_1 は gsub_alternate. 拼音が複数の漢字

rclt は多音字の置換に利用している。この feature は (文脈連鎖依存の置換、文脈依存の異体字) の表示のために利用できる。
pattern one は 熟語の中で 1文字だけ拼音が変化するパターン
pattern two は 熟語の中で 2文字以上拼音が変化するパターン
exception pattern は 例外的なパターン
詳細へ

仕様(制約)

  • このフォントは横書きのみ想定

  • glyf table は 65536 までしか格納できない

  • glyf table は大きいので別の json として保存している

  • 重複して定義されている漢字をグリフ数削減のために同一のグリフを参照するようにしている( ⺎:U+2E8E, 兀:U+5140, 兀:U+FA0C と 嗀:U+55C0, 嗀:U+FA0D )

  • 拼音のグリフとして使えるフォントは等幅英字のみ

  • python の標準ライブラリの json は dict に変換すると肥大化して遅くなるので、 orjson を利用する
    refer to Choosing a faster JSON library for Python, PythonのJSONパーサのメモリ使用量と処理時間を比較してみる

  • ss00 - 20 まで
    Tag: 'ss01' - 'ss20'

  • glyf table 内の 拼音 は簡易表記(yī -> yi1) にする

  • 呣 m̀, 嘸 m̄ は unicode に含まれていないので除外

  • overwrite.txt は色々な目的のために追加している
    pypinyin で取得できない漢字
    発音の優先度の調整
    儿 の r の追加
    軽声の追加、重複する漢字は同じ発音にする
    呣 m̀, 嘸 m̄ を除外するため(追加してもいいが拼音グリフを作るのが面倒になる)

  • IVS は

code Pinyin glyf
0xE01E0 何もないグリフ
0xE01E1 標準的な拼音
0xE01E2 以降、異読の拼音
  • ssXX と拼音の対応は以下のようにする
    -> ssXX に標準的な拼音を入れないと cmap_uvs で標準の読みに戻す場合に、すぐにGSUBが効いて元に戻ってしまう。そのため、ss01 に標準的な拼音に戻す用のグリフを用意する.
命名規則 グリフタイプ
hanzi_glyf 標準の読みの拼音
hanzi_glyf.ss00 拼音の無い漢字グリフ。設定を変更するだけで拼音を変更できる
hanzi_glyf.ss01 (異読の拼音があるとき)標準の読みの拼音(hanzi_glyf と重複するが GSUB の置換(多音字のパターン)を無効にして強制的に置き換えるため)
hanzi_glyf.ss02 (異読の拼音があるとき)以降、異読な拼音
  • lookup table の名前は自由だけど、どこから参照しているか分かりやすくするために名前を以下のようにする
lookup table name reference source
lookup_pattern_0N pattern one
lookup_pattern_1N pattern two
lookup_pattern_2N exception pattern
  • duoyinzi_pattern_one.txt の 1~n の並びは、marged-mapping-table.txt に従う。1 が標準的な読み. ss01 と合わせる

    U+5F3A: qiáng,qiǎng,jiàng  #强
    
    1, 强, qiáng, [~调|~暴|~度|~占|~攻|加~|~奸|~健|~项|~行|~硬|~壮|~盗|~权|~制|~盛|~烈|~化|~大|~劲]
    2, 强, qiǎng, [~求|~人|~迫|~辩|~词夺理|~颜欢笑]
    3, 强, jiàng, [~嘴|倔~]
    
  • lookup rclt は、読みのパターンごとにまとめる。 rclt0 は pattern one。 rclt1 は pattern two。 rclt2 は exception pattern.

  • duoyinzi_pattern_two.jsonduoyinzi_exceptional_pattern.json は Graphs like な記述

  • duoyinzi_exceptional_pattern.json の ignore tag では 影響する漢字に ' をつける

利用している用語

pypinyinで拼音が見つからない漢字まとめ

FIX_PINYIN.md

参考資料

多音字

辞書サイト

規格