読者です 読者をやめる 読者になる 読者になる

TTXを使用してTrueTypeフォントのglyfテーブルを修正

Font

IPAゴシック」フォントの「‼」(U+203C)、「⁉」(U+2049)の字形を修正する。ただしFontForgeをフォント出力に使わない。TTX/FontToolsでglyfテーブルを書き換えてフォントを出力する。

TTXを使用してTrueTypeフォントのcmapテーブルを修正
http://itouhiro.hatenablog.com/entry/20141004/font
の続き

[話者] Unicodeには「!!」「!?」をそれぞれ1文字にした

‼  U+203C
⁉  U+2049

が用意されているんだが、全角幅と規定されていない。

[合いの手] 漫画のセリフでよく使われてるね。漫画のセリフはたいてい縦書きだから、全角になってると便利なんだけど。 ところで「規定」ってどこかにルールでもあるのかい?

[話者] wikipedia:東アジアの文字幅http://www.unicode.org/reports/tr11/ に解説があるよ。具体的には http://www.unicode.org/Public/UCD/latest/ucd/ にある EastAsianWidth.txt が決めてる。

203C..203D;N     # Po     [2] DOUBLE EXCLAMATION MARK..INTERROBANG
...
2047..2051;N     # Po    [11] DOUBLE QUESTION MARK..TWO ASTERISKS ALIGNED VERTICALLY

とある。203Cも2049も N つまり「日本語圏では使われていなかった」とかいう理由で幅が決まってない。全角にしてるフォントもあるけど、IPAゴシックでは半角なんだよね。

そこで、手作業で全角にしてみるだろ。

FontForgeで字形修正

もともとは半角。

f:id:itouhiro:20141004175119p:plain

[メトリック>幅を設定]で2048にして全角幅にする。全角!?の字形をコピーペーストする。

f:id:itouhiro:20141004175133p:plain

FontForgeで[ファイル>フォントを出力] でTrueTypeフォントを出力する。[ ] Validate Before Savingのチェックを外すと素早く保存されるぞ。

f:id:itouhiro:20141004175304p:plain

ちなみにFontForgeの[ファイル>保存]でsfdファイルを保存して、そのsfdファイルを読む込むと何かおかしくなっていたりする。sfdよりttfで保存するほうがむしろ信頼性があると感じる。

[合いの手] でもFontForgeIPAゴシックを「TrueTypeフォント」出力すると、 http://itouhiro.hatenablog.com/entry/20140910/font に書いたとおりフォントがおかしくなるよね。直さなくていいの?

[話者] 直さなくていいよ。字形変更したTrueTypeフォントで、実際に使うのはglyfテーブルだけだからね。

TTXで字形置き換え

双方のglyfテーブルをTTXで出力する。 ipag.ttfが変更前のフォント。 IPAGothic.ttf は変更したフォント。

$ ttx -t glyf ipag.ttf
Dumping "ipag.ttf" to "ipag.ttx"...
Dumping 'glyf' table...

$ ttx -t glyf IPAGothic.ttf
Dumping "IPAGothic.ttf" to "IPAGothic.ttx"...
Dumping 'glyf' table...

$

このあと、ipag.ttxファイルを書き換える。 IPAGothic.ttxに含まれる、変更した字形のグリフ名(aj12111.hwaj12112.hw)の箇所だけを、ipag.ttxに持ってくればいい。

手作業でテキストエディターで書き換えてもいいんだけど、ttxファイルひとつで52MBもあったりして、あと何文字も置き換えるのはスクリプトのほうが確実なので、ここではnode.jsスクリプトで書き換えることにする。

glyfReplace.js

var fs = require('fs');

if (process.argv.length != 4){
  console.log('usage: node this.js origianl.ttx newglyph.ttx');
  process.exit(1);
}

var replaceCharacters = 'aj12111.hw aj12112.hw'; //U+203C, U+2049

var repChars = replaceCharacters.split(' ');
var orgFile = fs.readFileSync(process.argv[2]) + '';
var glyfFile = fs.readFileSync(process.argv[3]) + '';

var i;
for(i=0; i<repChars.length; i++){
  var re = '[ \t]*<TTGlyph name="' +repChars[i]+ '"[\\s\\S]*?</TTGlyph>'; 
  var re2 = '[ \t]*<TTGlyph name="' +repChars[i]+ '"/><!-- contains no outline data -->'; 
  var matchGlyph = glyfFile.match(RegExp(re));
  var newGlyph = matchGlyph[0];

  var m;
  var matched;
  if (m = orgFile.match(re)){
    //console.log('orgFile match ' + repChars[i]);
    matched = m[0];
    orgFile = orgFile.replace(matched, newGlyph);
  }else{
    console.log(repChars[i] + ' not match.');
    m = orgFile.match(re2);
    if (m){
      matched = m[0];
      orgFile = orgFile.replace(matched, newGlyph);
    }else{
      console.log(repChars[i] + ' not match. ignored.');
    }
  }
}
fs.writeFileSync('new.ttx', orgFile);

このスクリプト

$ node glyfReplace.js ipag.ttx IPAGothic.ttx

と使うと、新しく new.ttx が作られる。

それを使って、もとのipag.ttfのglyfテーブルを置き換え。

$ ttx -m ipag.ttf new.ttx
Compiling "new.ttx" to "new.ttf"...
Parsing 'glyf' table...

new.ttfが修正版のフォントだ。

f:id:itouhiro:20141004182718p:plain

[合いの手] 確かに変わったぞ。

 

 

 

Fonts & Encodings

Fonts & Encodings