« 2008年1月 | トップページ | 2008年3月 »

2008年2月

2008年2月28日 (木)

OpenTypeフォントの続き(6)・・・cmapテーブル

今回はcmapテーブル

cmapテーブルは文字コードからグリフインデックスへのマッピングを定義するテーブルで、必須である。また、様々なプラットフォーム・エンコーディング向けに複数のサブテーブルを定義することができる。

cmapテーブルの構造は、cmapヘッダーで始まり、次のようになる。

cmap ヘッダー
名前 説明
USHORT Version テーブルバージョン
USHORT NumTables エンコーディングテーブル数
EncodingRecord EncodingRecords[NumTables] エンコーディングレコードの配列

NumTablesフィールドはcmapテーブルに含まれるエンコーディングサブテーブルの数を表し、EncodingRecordsフィールドはエンコーディングレコードの配列を表す。各エンコーディングレコードの構造は次のようになる。

エンコーディングレコード
名前 説明
USHORT PlatformID プラットフォームID
USHORT EncodingID プラットフォーム固有のエンコーディングID
ULONG Offset cmapテーブルの先頭からのエンコーディングサブテーブルへのオフセット(バイト単位)

PlatformIDEncodingIDフィールドの表す値は、nameテーブルの回で説明した通りである。Offsetフィールドはcmapテーブルの先頭からのエンコーディングサブテーブルへのオフセットを表し、この値を使って、各エンコーディングサブテーブルにアクセスする。次にエンコーディングサブテーブルの構造であるが、エンコーディングの特性に応じて、複数のフォーマットが定義されている。各フォーマットの概要は次のようになる。

エンコーディングサブテーブルフォーマット
種類 概要
フォーマット0 Byte encoding table
フォーマット2 High-byte mapping through table
フォーマット4 Segment mapping to delta values
フォーマット6 Trimmed table mapping
フォーマット8 mixed 16-bit and 32-bit coverage
フォーマット10 Trimmed array
フォーマット12 Segmented coverage

フォーマット0は、1バイトエンコーディングフォーマットである。フォーマット2は、混合8/16ビットエンコーディングフォーマットで、1バイトと2バイトの文字コードが混在する日本語のShift-JISなどで使われる。フォーマット4は2バイトエンコーディングフォーマットである。フォーマット8、10、12は4バイトエンコーディングフォーマットである。MicrosoftはWindows向けのサロゲートペアに対応したUnicodeフォントを作成する時、フォーマット4とフォーマット12を組み合わせて使うように推奨している。ちなみに、どのフォーマットが使われているかを判定するには、各エンコーディングサブテーブルの先頭2バイトがフォーマットの種類を表すFormatフィールドで始まるので、このフィールドを参照して判定できる。

各フォーマットの詳細は割愛するとして、実際にcmapテーブルを解析してみた。

Opentype7_1

上の画像はTahomaフォント(TAHOMA.TTF)を解析した時の実行結果である。MacintoshプラットフォームとMicrosoftプラットフォーム向けの2つのエンコーディングサブテーブルが含まれていることが分かる。Microsoftプラットフォーム向けのエンコーディングサブテーブルは、Unicodeエンコーディングでフォーマット4が使われていることも分かる。Macintoshプラットフォーム向けのエンコーディングサブテーブルは、下の画像が示す通り、フォーマット0が使われている。

Opentype7_2

実際に、TAHOMA.TTFファイルをMacintosh上でそのまま使えるかは分からないが、フォーマット0は1バイト文字コード向けのフォーマットなので、Macintosh上では、最大256個のグリフまでしかアクセスできないことになる。

最後にいつもならMS ゴシックフォントを解析するところだが、結果がTahomaフォントとあまり変わらないので、インターネット上で見つけた無料のフォントを解析してみた。

Opentype7_3

Macintoshプラットフォーム向けにShift-JISのエンコーディングサブテーブルが定義されていて、フォーマット2が使われていることが分かる。

2008年2月18日 (月)

OpenTypeフォントの続き(5)・・・OS/2テーブル

今回はOS/2テーブルである。OS/2テーブルはOS/2・Windows固有のメトリックスを定義するテーブルで必須である。前回と同様に、先に実行結果を示す。

Opentype6_1

上の画像はMS ゴシックフォントを解析した時の実行結果である。WeightClassはフォントの太さを表すフィールドで、windows.hで定義されているFW_NORMALやFW_BOLD等の値をとる。FsSelectionはフォントのスタイルを表すビットフィールドである。UnicodeRangeはフォントが提供しているグリフによってカバーされるUnicodeブロックを表すビットフィールドである。同様に、CodePageRangeはフォントが提供しているグリフによってカバーされるコードページ(文字コード)を表すビットフィールドである。上の画像より、日本語の文字コードであるShift-JIS(SHIFTJIS_CHARSET)に対応するビット17がセットされていることがわかる。また、上の画像からは判断できないが、MS ゴシックフォントには、ラテン文字やギリシャ文字のグリフも含まれているので、それらに対応するビットもセットされている(ANSI_CHARSETやGREEK_CHARSETなどに対応するビット)。

通常、Windowsでフォントを指定する時、LOGFONT構造体で表される論理フォントで指定するが、実際にはWindowsのフォントマッパによって、指定された論理フォントに近い物理フォントが選択される。この時、フォントマッパはフォントのこれらのフィールドをLOGFONT構造体のフィールドと比較していると思われる。例えば、LOGFONT構造体のlfWeightフィールドはOS/2テーブルのWeightClassフィールド、lfCharsetフィールドはOS/2テーブルのCodePageRangeフィールドという具合に(lfFaceNameフィールドはOS/2テーブルではなくnameテーブル)。

ところで、OS/2テーブルのUnicodeRangeやCodePageRangeフィールドの表す値は、Win32APIのGetTextCharsetInfoなどで返されるFONTSIGNATURE構造体として取得できるので、それらの値も括弧付きで示してある。他にもFamilyClassPanoseフィールドなどおもしろそうなフィールドもあるが、省略・・・

最後に、TahomaフォントのOS/2テーブルを解析した時の実行結果を示す。

Opentype6_2

というか、ずっとフォントの話ばっかりなので、しばらく他の話題にしようかと思っている。肝心のcmap・glyfテーブルやOpenTypeテキストレイアウトテーブルと呼ばれるGSUB・GPOSテーブルのことにほとんど触れていないが・・後、この作ってるツールをある程度完成したら、ダウンロードできるようにもしようかなと。

2008年2月14日 (木)

OpenTypeフォントの続き(4)・・・head・maxpテーブル

今回はheadテーブルmaxpテーブル

というより、書くのがだるくなってきたので、さらりと行こうと思う。despair

まずは、headテーブル。headテーブルはフォントのグローバルな情報を定義するテーブルで必須である。先に、MS ゴシックフォントを解析した時の実行結果を示す。

Opentype5_1

順番が前後するかも知れないが、まずは、UnitsPerEm。UnitsPerEmは、Em四角形辺りのユニット数を表す。MacStyleはフォントのスタイルを表すビットフィールドである。Windows固有のメトリックスを表すOS/2テーブルにもフォントのスタイルを表すfsSelectionフィールドがあるが、Windowsの場合、OS/2テーブルのfsSelectionを優先するようである。

Opentype5_2

上の画像は、Arial Boldタイプフェイス(わかりやすく言うと、ArialフォントのBoldスタイル、ファイル名はARIALBD.TTF)を解析した時の実行結果であるが、Boldスタイルを表すMacStyleのビット0がセットされていることが分かる。

で、次はmaxpテーブルである。これはフォントのプロファイルを表すテーブルである。これもheadテーブルと同じように、解析した実行結果を先に示す。

Opentype5_3

上の画像はTahomaフォント(TAHOMA.TTF)を解析した結果である。フィールド名を見れば分かるように、NumGlyphsは含まれるグリフの数を表す。Tahomaフォントの場合、1283個のグリフが含まれていることが分かる。MaxPointsMaxContoursは通常のグリフ(コンポジットグリフではないグリフ)を構成する点、輪郭線の数の最大値を表す。以下省略・・・

というか、タイポグラフィ関連の専門用語はややこしいなぁ。

追記:ちなみに、フォントに含まれるグリフの数を表すmaxpテーブルのNumGlyphsや他のテーブルのNumGlyphsはUSHORT型つまり2バイトの符号無し整数として宣言されているので、いうまでもなく、TrueTypeやOpenTypeフォントには65536個以上のグリフを含めることはできない。

2008年2月11日 (月)

OpenTypeフォントの続き(3)・・・nameテーブル

ということで今回はnameテーブル

nameテーブルは、フォントファミリ名・フォントの著作権注釈など、フォントに関する文字列データを定義するテーブルである。nameテーブルの構造は次のようになる。

nameテーブル
名前 説明
USHORT format フォーマットセレクタ(=0)
USHORT count Nameレコードの数
USHORT stringOffset テーブルの先頭からの文字列ストレージへのオフセット(バイト)
NameRecord nameRecords[count] nameレコードの配列
(Variable) 文字列ストレージ

Nameレコードの構造は次のようになる。

Nameレコード
名前 説明
USHORT platformID プラットフォームID
USHORT encodingID プラットフォーム固有のエンコーディングID
USHORT languageID 言語ID
USHORT nameID 名前ID
USHORT length 文字列の長さ(バイト)
USHORT offset 文字列ストレージの先頭からの文字列へのオフセット

プラットフォームIDはプラットフォームの種類を表すIDで次のような値になる。

プラットフォームID
プラットフォームID プラットフォーム名
0 Unicode
1 Macintosh
2 ISO
3 Microsoft
4 カスタム

MicrosoftのWindows向けのフォントでは、通常、プラットフォームID=3が使われる。次のエンコーディングIDは、プラットフォーム固有のエンコーディングを表すIDで、例えば、プラットフォームID=3のMicrosoftプラットフォームでは、次のような値になる。

エンコーディングID(プラットフォームID=3)
エンコーディングID 説明
0 シンボル
1 Unicode BMP面のみ
2 シフトJIS
3 PRC
5 Big5
6 Johab
7 予約済み
8 予約済み
9 予約済み
10 Unicode フルレパトリー

Windows向けのUnicodeフォントの場合、通常、エンコーディングID=1もしくは10、シンボルフォントの場合、0が使われる。次に言語IDであるが、Microsoftプラットフォーム(プラットフォームID=3)の場合、Windowsのロケール(LCID型のロケールID) を表す。最後に、名前IDであるが、これは文字列データの内容を表すIDで、次のような値になる。

名前ID
名前ID 説明
0 著作権注釈
1 フォントファミリ名
2 フォントサブファミリ名
3 フォント識別子
4 完全なフォント名
5 バージョン文字列
6 PostScript名
7 商標
8 製造社名
・・・以下省略・・・

以上を踏まえて、実際にnameテーブルを解析してみた。実行結果は次のとおり。

Opentype4_1_3

上の画像はMS ゴシックフォントのnameテーブルを解析したときの実行結果である。MicrosoftとMachintoshプラットフォーム向けの文字列データが含まれていることが分かる。また、Microsoftプラットフォーム(プラットフォームID=3)向けの文字列データは、Unicode(エンコーディングID=1)でエンコードされ、英語ロケール(ロケールID=0x0409)と日本語ロケール(ロケールID=0x0411)向けの2種類含まれていることもわかる。アプリケーション側でこれらの情報をユーザーに対して表示する時、アプリケーションの実行環境のロケールに合わせて切り替えれば、よりユーザーフレンドリになることは言うまでもない。

ちなみに、上の画像のNameRecords & String DataリストビューのString Data列は文字列データを16進数で表示した値である。String Data(Encoded)列は文字列データをプラットフォームID、エンコーディングIDで指定されたエンコーディングで符号化し、表示できるようUnicodeに変換して表示した値である。Macintosh向けの文字コードはよくわからないので、空白にしておいた。

最後に、Tahomaフォントのnameテーブルを解析した時の実行結果も載せておく。

Opentype4_2

追記:Macintosh向けの文字コードはよくわからないと書いたが、Windowsには、Mac用のいくつかのコードページがインストール・サポートされているので、Win32APIのMultiByteToWideCharを使ってUnicodeに変換してみた。

Opentype4_3

Macintoshプラットフォーム(PlatformID=1)のEncodingID=0(Roman)は、Windowsコードページ10000に対応するようなので、コードページ10000を指定して、MultiByteToWideCharを呼び変換してみたが、上手くいったようである。

2008年2月 7日 (木)

OpenTypeフォントの続き(2)・・・OpenTypeテーブル

1回目でTahomaフォントのファイル(TAHOMA.TTF)に含まれるテーブルの一覧を列挙したが、今回はOpenTypeフォントのテーブルの概要について。

前にOpenTypeフォントは、グリフデータとしてTrueType形式のアウトラインもしくはPostScript形式のアウトラインを含むことができると書いたが、アウトラインの形式にかかわらず正しく機能するために、以下のテーブルが必須である。

必須テーブル
タグ 名前
cmap 文字・グリフマッピング
head フォントヘッダー
hhea 水平ヘッダー
hmtx 水平メトリックス
maxp 最大プロファイル
name 名前テーブル
OS/2 OS/2・Windows固有メトリックス
post PostScript情報

cmapテーブルは文字コードとグリフインデックスのマッピングを定義するテーブルで、1つ以上の文字エンコーディングをサポートするために、複数のマッピングサブテーブルを含むことができる。nameテーブルはフォントファミリ名・サブファミリ名・著作権注釈などのフォントに関連する文字列を定義するテーブルである。OS/2テーブルは、OS/2・Windowsに固有のメトリックスを定義するテーブルである。

TrueTypeアウトラインに基づくOpenTypeフォントでは、次のテーブルが使われる。

TrueTypeアウトライン関連のテーブル
タグ 名前
cvt コントロール値テーブル
fpgm フォントプログラム
glyf グリフデータ
loca インデックス・位置
prep CVTプログラム

PostScriptアウトラインに基づくOpenTypeフォントでは、次のテーブルが使われる。

PostScriptアウトライン関連のテーブル
タグ 名前
CFF PostScriptフォントプログラム
VORG Vertical Origin

OpenTypeフォントは小さなフォントサイズのために最適化されたビットマップを含むことができるが、そのために次のテーブルが使われる。

ビットマップグリフ関連のテーブル
Tag 名前
EBDT ビットマップデータ
EBLC ビットマップ位置データ
EBSC ビットマップスケーリングデータ

アドバンストタイポグラフィテーブル
Tag 名前
BASE ベースラインデータ
GDEF グリフ定義データ
GPOS グリフ配置データ
GSUB グリフ置換データ
JSTF ジャスティフィケーションデータ

その他のテーブル
Tag 名前
DSIG デジタル署名
gasp グリッドフィティング/スキャンコンバーション
hdmx 水平デバイスメトリックス
kern カーニング
LTSH Liner threshold data
PCLT PCL 5 data
VDMX 垂直デバイスメトリックス
vhea 垂直メトリックスヘッダー
vmtx 垂直メトリックス

ということで、次回以降、これらのテーブルの内のいくつかを見ていこうと思う。というより、上に挙げた大半のテーブルを理解していないdespair

2008年2月 6日 (水)

OpenTypeフォントの続き(1)・・・TTC

今回は前回最後に触れたTrueType Collectionについてである。

TrueType Collection(TTC)とは、1つのファイルに複数のOpenTypeフォントを格納するためのファイルフォーマットで、拡張子は通常.TTCである。また、複数のOpenTypeフォントをただ単純に1つのファイルにパッケージングするのではなく、フォント間でグリフを共有して、ファイルサイズを抑えるための仕組みが備わっている。

TTCの構造は次のようになる。(前回同様、概念的な図である。)

Opentype2_1_2

TTCはTTCヘッダーから始まる。つまり、TTCの先頭(オフセット0)にTTCヘッダが格納されていなければならない。また、TTCヘッダの構造は次のようになる。

TTCヘッダ Version1.0
名前 説明
TAG TTCTag TrueType Collection ID:'ttcf'
ULONG Version TTCヘッダのバージョン:0x00010000
ULONG numFonts TTC内のフォント数
ULONG offsetTable[numFonts] TTC内の各フォントへのファイルの先頭からのオフセット(バイト)

TTCヘッダ Version2.0
名前 説明
TAG TTCTag TrueType Collection ID:'ttcf'
ULONG Version TTCヘッダのバージョン:0x00020000
ULONG numFonts TTC内のフォント数
ULONG offsetTable[numFonts] TTC内の各フォントへのファイルの先頭からのオフセット(バイト)
ULONG DsigTag DSIGテーブルが存在するかを表すタグ。存在すれば、0x44534947('DSIG')
ULONG DsigLength DSIGテーブルのサイズ(バイト)
ULONG DsigOffset DSIGテーブルへのファイルの先頭からのオフセット(バイト)

numFontsはTTC内のフォント数を表す。OffsetTableは各フォントへのファイルの先頭からのオフセットの配列で、TTC内のフォントの数つまりnumFontsの数だけ要素がある。このオフセットの配列を使って、TTC内の各フォントにアクセスする。TTC内の各フォントの構造は前回説明したものと同じである。

ここで注意が必要なのは、TTC内の各フォント内のテーブルへのアクセスである。前回、各テーブルへはテーブルディレクトリエントリのOffsetフィールドを使ってアクセスできると書いたが、このテーブルディレクトリエントリのOffsetフィルードはTTCファイルであろうとなかろうと、常にファイルの先頭からのオフセットを表す。

以上を踏まえて、TTCヘッダを解析するプログラムを作成してみた。実行結果はこんな感じである。

Opentype2_2

MSゴシック系のTTCファイル(MSGOTHIC.TTC)を解析した時の実行結果である。このTTCファイルに3つのOpenTypeフォントが含まれていることがわかる。ちなみに、Windowsのエクスプローラでこのファイルを見れば分かるように、このファイルにはMS ゴシック、MS Pゴシック、MS UI Gothicの3つのフォントが含まれていることが分かる。

Opentype2_3

2008年2月 5日 (火)

OpenTypeフォント

今回からOpenTypeフォント

OpenTypeフォントはTrueType Open V2.0フォントとも呼ばれ、Microsoft社とAdobe社によってTrueTypeフォントを拡張して開発されたフォントである。また、グリフデータとして、TrueType形式のグリフデータもしくはPostScript形式のグリフデータを含むことができるアウトラインフォントであるが、小さいフォントサイズ用にビットマップ形式のグリフデータを含むこともできる。

で、今回から、このOpenTypeフォントのファイルを解析してみる。ちなみに、TrueType形式のグリフデータを含むOpenTypeフォントのファイルの拡張子は通常.TTF.OTFである。

OpenTypeフォントの構造は、フォントに関する様々な情報が格納された名前(タグと呼ばれる)付きのテーブルの集まりから構成され、下の図のようになる。

Opentype1_1

OpenTypeフォントは、最初にバージョン番号やフォント内のテーブル数が格納されたオフセットテーブル(Offset Table)から始まる(オフセット=0)。そしてすぐ後に、フォント内の各テーブルのタグ名や開始位置(オフセット)やサイズが格納されたテーブルディレクトリ(Table Directory)が続く。ちなみに、上の図は概念的な図である。

オフセットテーブルの構造は次のようになる。

オフセットテーブル
名前 説明
Fixed sfnt version 0x00010000 for version 1.0
USHORT numTables テーブル数
USHORT searchRange
USHORT entrySelector
USHORT rangeShift

numTablesはフォント内のテーブル数である。テーブルオフセットのすぐ後に続くテーブルディレクトリはテーブルディレクトリエントリの配列で、numTable個のエントリが含まれる。テーブルディレクトリエントリの構造は次のようになる。

テーブルディレクトリエントリ
名前 説明
ULONG tag 4バイト識別子(タグ名)
ULONG checkSum テーブルのチェックサム
ULONG offset テーブルのファイルの先頭からのオフセット(バイト)
ULONG length テーブルのサイズ(バイト)

tagはテーブルに付けれたタグの名前で、印字可能なASCII文字でなければならない。offsetはテーブルのファイルの先頭からのオフセット、lengthはテーブルのサイズを表す。つまり、offsetとlengthを使ってフォント内の各テーブルにアクセスする。

以上のことを踏まえて、OpenTypeフォント内に含まれているテーブルを列挙するプログラムを作成してみた。

Opentype1_2

上はWindows2000に含まれているTahomaフォントのファイル(ファイル名TAHOMA.TTF)を解析した時の実行結果である。Tahomaフォントのファイルには、21個のテーブルが含まれ、例えば、cmapやnameというタグ名の付いたテーブルが含まれていることが分かる。また、各テーブルのファイルの先頭からのオフセットやサイズも分かる。ちなみに、OpenTypeフォントファイルのバイトオーダーはモトローラ形式のビッグエンディアンなので、Intel系のCPUを使うWindows上で読み書きする時には、バイトオーダーをリトルエンディアンに変換する必要がある。

また、Tahomaフォントは欧文用のフォントで、本来は日本語環境のユーザーに馴染み深いMSゴシックなどのフォントの実行結果を載せたいところであるが、MS ゴシックやMS明朝などのフォントはTrueType Collectionというファイルフォーマットになっているので、今回は割愛した。

ということで次回に続く?。

« 2008年1月 | トップページ | 2008年3月 »

自作ソフトウェア

無料ブログはココログ

メモ