ttc2ttfなことをしたかったので探してたらこんなありがたいスクリプトを発見。

通常ほとんど意識することはありませんが、フォントファイルの中にはTTC(TrueType Collection)という形式のファイルがあります。これはその名の通りTrueTypeフォントをいくつかまとめたものですが、フォントファイルをいじくりたいときには扱えなかったり、Linuxで扱いたくても扱えなかったりということがあります。そんな時は通常のTTFファイルに分割すれば操作できるようになるようです。
以前はMicrosoftから分割用のプログラムが配布されていたようですが、最近は公開されていない(まあ、ネットで探せば転がってますが)のでPerlで作ってみました。単純にTTCを分割したい場合に使えます。
(中略)
TTC形式はシンプルなフォーマットで、TTFファイルをまとめただけ、というような形式です。本スクリプトでは以下のような処理をしています。もっと細かい動作はスクリプトを読んでください。なお、対応しているTTCはVersion 1のみです(2にも使えるかもしれませんが、手元に確認環境がありません・・・)。
(中略)
動作確認:Perl 5.10.0 (Vine Linux 5.0)

Happy Scripting/TTCファイルを分解する - BioKids Wiki

ということで公開されていたスクリプトを Perl 5.8 & FreeBSD な環境で動かしたら「use open IO => ":raw";」の部分でエラーが出てしまった。Perlのバージョンの問題かな?よくわからないけどとりあえず「binmode STDOUT => ":raw";」に変更してみたら動いたので、そのコードが以下。


#!/usr/bin/perl
# SplitTTC for spliting TTC file.
# by Nob-rin,2009
# 2009-10-20
 
use strict;
# use open IO => ":raw"; # ここでエラーが出たので
binmode STDOUT => ":raw"; # こっちにしてみた
 
$| = 1;
my $TTC = {};                 # TTC header info
my @TTFS;                     # TTF header info list
my $OUTFILE = "out%02d.ttf";  # Output file name template
 
# Open TTC file
my $buf;
if($ARGV[0] eq ""){ print "Usage: splitttc TTCFile\n"; exit(0); }
open(my $fh,$ARGV[0]) || die "Can't open $ARGV[0] [$!]\n";
read($fh,$buf,12);
(@$TTC{qw/TTCTag Version numFonts/}) = unpack("A4H8N1",$buf);
$TTC->{TTCTag} eq "ttcf" && $TTC->{Version} eq "00010000" || die "Format error. File mu> st be TTC ver.1.\n";
 
# Reading TTF headers
for(my $i=0;$i<$TTC->{numFonts};$i++){
    my $ttf = {};
    read($fh,$buf,4);
    $ttf->{offset} = unpack("N1",$buf);
    push(@TTFS,$ttf);
}
 
# Reading TTF tables
foreach my $ttf (@TTFS) {
    seek($fh,$ttf->{offset},0);
    read($fh,$buf,12);
    @$ttf{qw/sfntVersion numTables searchRange entrySelector rangeShift/} = unpack("H8n> nnn",$buf);
    $ttf->{tables} = [];
    for(my $i=0;$i<$ttf->{numTables};$i++){
        read($fh,$buf,16);
        my $h = {};
        @$h{qw/tag checkSum offset length/} = unpack("a4NNN",$buf);
        push(@{$ttf->{tables}},$h);
    }
}
 
# Writing out TTF files
my $cnt = 0;
foreach my $ttf (@TTFS) {
    my $fname = sprintf($OUTFILE,$cnt);
    print "Writing $fname ... ";
    open(my $out,sprintf(">$fname",$cnt));
 
    # Space for TTF header
    print {$out} chr(0) x 12;                       # TTF header
    print {$out} chr(0) x (16 * $ttf->{numTables}); # TTF tables
 
    # Writing TTF data body
    foreach my $t (@{$ttf->{tables}}) {
        seek($fh,$t->{offset},0);
        read($fh,$buf,$t->{length});
        if($t->{length} % 4){ $buf .= chr(0) x (4 - $t->{length} % 4) }    # Insert pad> ding
        $t->{offset} = tell($out);  # Getting offset value
        print {$out} $buf;
    }
 
    # Write TTF headers
    seek($out,0,0);
    print {$out} pack("H8nnnn",@$ttf{qw/sfntVersion numTables searchRange entrySelector>  rangeShift/});
    foreach my $t (@{$ttf->{tables}}) {
        print {$out} pack("a4NNN",@$t{qw/tag checkSum offset length/});
    }
 
    close $out;
    print "Done\n";
    $cnt++
}
 
close $fh;

んで、こんな感じで実行したら

$ perl splitttc.pl msgothic.ttc

無事にttfファイルが生成された。

参考までにWikipediaの記述とか。

TrueType Collection (TTC) is an extension of TrueType format that allows combining multiple fonts into a single file, creating substantial space savings for collection of fonts that only use different glyphs on some characters. They were first available in Chinese, Japanese, and Korean versions of Windows, and supported for all regions in Windows 2000 and later.

TrueType - Wikipedia, the free encyclopedia
拡張子は「.TTF」と「.TTC」の二種類。前者は単体のフォントファイルであり、後者は類似した複数のフォントを1つのファイルに収納したものである(例えば、1つのTTCファイルにプロポーショナルフォント+等幅フォントが内包されたものなど)。

TrueType - Wikipedia

tags: Font Perl zurazure

Posted by NI-Lab. (@nilab)