「名前」テーブルで作業します | .NET

TrueTypeフォントテーブル「名前」は、そのフォントに関連するテキスト文字列のストレージです。これらの文字列は、さまざまな言語で記述でき、フォント名、姓、デザイナー名、ライセンス情報、著作権通知など、さまざまなエンティティを表すことができます。 要するに、テーブル「名前」に保持されている行は、フォントメタデータを説明しています。

「名前」テーブルのスキーマ。

「名前」テーブルの詳細な仕様にアクセスできます Microsoftおよび Appleドキュメント。

それに応じて番号0と1の「名前」テーブルには2つの形式があります。 「名前」テーブルに関しては、これらの形式番号はバージョンとして名前が付けられているため、形式0は バージョン0、形式1- バージョン1として指定されます。

形式1は、言語識別のフォーマット0とは異なります。 「名前」テーブルのエントリには、その文字列の言語を検出するために使用される言語識別子があります。フォーマット0とフォーマット1の違いは、これらの言語識別子の解釈方法です。

フォーマット0の言語識別子にはプラットフォーム固有の解釈がありますが、形式1の言語識別子は言語タグ文字列に関連付けられており、プラットフォームに関係なく言語を識別します。

より正確にするために、フォーマット1を使用すると、両方のタイプの言語識別子を維持できます - プラットフォーム固有の解釈を持つ識別子と、言語タグ文字列に関連する識別子(つまり、プラットフォームから独立しています)。

Aspose.Font Libraryは、「名前」テーブルのフォーマット0をサポートしています。フォーマット1のサポートは、将来のリリースのために計画されています。

「名前」テーブルが持っている形式とは独立して、このテーブルのすべてのエントリは特定のコンポーネント構造 namerecordに基づいています。

この構造の4つの主なパラメーターは次のとおりです。

パラメーターPlatformId、Platformspecifid、およびLanguageIDは、文字列の言語をプラットフォーム固有の方法で設定するために使用されます。 PlatformIDパラメーターのコンテキストでのみ、パラメーターの値PlatformspecificidとLanguageIDは重要です。

たとえば、Platformspecificid equal 0はMACプラットフォームのローマスクリプトを定義し、同時にPlatformspecificidはWindowsプラットフォームのローマスクリプトを定義します。 同様に、LanguageIDの値は、使用されているPlatformIDパラメーターのコンテキストでのみ重要です。

たとえば、LanguageID英語USAを定義するPlatformID = 1(MAC)の場合は0、PlatformId= 3(Windows)が0x0409に等しい。

除外は、プラットフォームに関係なく言語を識別する言語タグ文字列に関連付けられている名前テーブル形式1のLanguageIDです。

パラメーターnameIdは数字であり、フォント名、姓などの論理文字列カテゴリを識別します。名前識別子には 事前定義されたセットがあります。これは、すべてのプラットフォームと言語で同じです。

したがって、条件付きでテーブル「名前」の各エントリは、3つの部分に分けることができます。

  1. 論理文字列カテゴリ、
  2. 文字列言語、
  3. 文字列自体。

パラメーターnameIdは、最初の部分に関連しています。パラメーターPlatformId、Platformspecifid、およびLanguageIDは2番目の部分に関連しています。

Aspose.Fontを使用して「名前」テーブルレコードを使用する方法は?

「名前」テーブルのサポートは、クラス ttfnametableによって提供されます。さらに、このオブジェクトの機能を検討します。 まず、 ttfnametableクラスの機能を使用して作業するために必要な列挙について説明しましょう。

上記のように、PlatformIDパラメーターのコンテキストでのみ、パラメータープラットフォーム固有のパラメーターの値とLanguageIDは重要です。」したがって、PlatformIDが0であり、これがUnicodeプラットフォームを定義する場合、 UnicodePlatformspecid列挙を使用します。PlatformIDが1(Macintoshプラットフォーム)の場合、 MacPlatformspecid列挙 *(Windows Platform)が3(Windows Platform)の場合、 msplatformspecid eNumerationを使用します。

列挙 mslanguageidおよび maclanguageidは、LanguageIDパラメーターに関連しています。 PlatformIDが3(Windows Platform)の場合、 MSLANGUAGEID列挙を使用し、PlatformIDが1(Macintoshプラットフォーム)の場合は MacLanguageID列挙を使用します。

次に、「名前テーブルから入手してリフレッシュする問題を進めましょう。

「名前」テーブルからレコードを取得する方法は?

メソッド getallnamerecords()から始めましょう。この方法は、その名前から次のように、「名前」テーブルの除外なしにすべてのエントリを返します。実際には、ほとんどの場合、ユーザーはすべてのエントリを必要としないため、ユーザーが呼び出されることはあまりないことが多いため、必要なエントリを取得するには、エントリのリストを徹底的にフィルタリングする必要があります。

問題は、たとえば、1つのロジックカテゴリであっても、このカテゴリの文字列データが異なる言語である可能性があることです。したがって、各言語には、このロジックカテゴリの「名前」テーブルに別のエントリが必要です。 Fontfamilyカテゴリのデータが英語、フランス語、ドイツ語に存在する場合のように、Fontfamilyカテゴリには3つのエントリが含まれます。

さらに、言語エントリは、文字列データ値とLanguageID値に一致するいくつかのエントリに分割することができますが、PlatformIdとPlatformspecifidパラメーターの値によって異なります。

「名前」テーブルからのデータサンプリングを簡素化するには、次の方法を提供します。

  1. このレコードは英語で書かれているため、valunedlanguageid.english_united_statesまたはmslanguageid.english_united_kingdomの値があります。
  2. このレコードには、 fontenvironment.current.currentplatformid(Microsoftプラットフォームを宣言する現在の実装では3)に等しい値を持つPlatformIDがあります。

「名前」テーブルにレコードを追加/更新する方法は?

classTTFNAMETABLEは、 addNameを提供して、「名前」テーブルにレコードを追加または更新します。

このメソッドは、 namerecordの型の構造を作成し、「名前」テーブルに挿入します。レコードがパラメーターPlatformId、Platformspecifid、LanguageID、およびnameIdによって追加されたものと一致する場合、メソッドは新しいレコードを追加しませんが、パラメーター「名前」で定義された値を使用して既存のレコードの文字列データを更新します。

パラメーター nameIdレコードの論理文字列カテゴリを定義します。パラメーターPlatformId、Platformspecifid、およびLanguageIDは、文字列の言語を設定するために使用されます。最後のパラメーター「名前」は、レコードの文字列データを設定するために使用されます。

ttfnametableオブジェクトの関数を使用する例。

次の名前空間に使用することを含めます。

1    using System;
2    using System.IO;
3    using System.Text;
4    using Aspose.Font;
5    using Aspose.Font.Sources;
6    using Aspose.Font.Ttf;
7    using Aspose.Font.TtfTables;

例で使用するフォントの読み込み

以下のスニペットでは、DataDir の TTF/montserrat-bold.ttf が font という名前の TtfFont 変数に読み込まれているものとします。読み込み手順については、 TrueType フォントの読み込み、データ抽出、保存を参照してください。

次の 2 つのスニペットは、フォントの完全名 の値を出力します。サンプルフォントでは、どちらも Montserrat Bold を返します。

1// Read the full font name by name ID
2
3string fullFontName = font.TtfTables.NameTable.GetNameById(TtfNameTable.NameId.FullName);
4Console.WriteLine("Full font name: {0}", fullFontName);
1// Read the English full font name from multilingual metadata
2
3string fullFontName = font.TtfTables.NameTable.GetMultiLanguageNameById(TtfNameTable.NameId.FullName).GetEnglishString();
4Console.WriteLine("Full font name: {0}", fullFontName);

定義済み名前 ID のレコードの出力

次のスニペットは、定義済みの TtfNameTable.NameId 値を列挙し、値が存在する各カテゴリについて、利用可能な各言語の文字列を出力します。

 1// Print name-table strings for predefined name IDs
 2
 3TtfNameTable.NameId[] ids = Enum.GetValues<TtfNameTable.NameId>();
 4
 5foreach (TtfNameTable.NameId nameId in ids)
 6{
 7    MultiLanguageString? mlString = font.TtfTables.NameTable.GetMultiLanguageNameById(nameId);
 8    if (mlString == null)
 9        continue;
10    Console.WriteLine(string.Format("{0}: {1}", nameId, GetMultiLanguageStringValue(mlString)));
11}
12// Format the available language values for each predefined name ID.
13string GetMultiLanguageStringValue(MultiLanguageString mlString)
14{
15    int[] languages = mlString.GetAllLanguageIds();
16    if (languages.Length == 1)
17        return mlString.GetEnglishString();
18
19    StringBuilder sb = new StringBuilder();
20
21    for (int i = 0; i < languages.Length; i++)
22    {
23        int langId = languages[i];
24        sb.Append(String.Format("{0}: {1}", (Enum.GetName<TtfNameTable.MSLanguageId>(
25            (TtfNameTable.MSLanguageId)langId) ?? langId.ToString()), mlString.GetStringForLanguageId(langId)));
26        if (i != (languages.Length - 1))
27            sb.Append(", ");
28    }
29
30    return sb.ToString();
31}

カテゴリ「フォントサブファミリー名」と「説明」の値を更新する

name テーブルのエントリを追加または更新するには、フォント内の既存レコードと一致するプラットフォーム ID、プラットフォーム固有 ID、および言語 ID を渡します。この例では、最初に一致する フォントサブファミリ レコードを更新します。サンプルフォントには 説明 レコードがないため、最初に見つかった名前レコードの ID を使用して新しいレコードを作成します。他のプラットフォームおよび言語のバリエーションは変更されません。

 1// Update font subfamily and description records
 2
 3// Use tuples so the complete operation fits in one method without a helper type.
 4(TtfNameTable.NameId NameId, string StringData)[] recordsToUpdate =
 5{
 6    (TtfNameTable.NameId.FontSubfamily, "Italic"),
 7    (TtfNameTable.NameId.Description, "New description")
 8};
 9
10TtfNameTable.NameRecord? firstRecord = null;
11foreach (var updateData in recordsToUpdate)
12{
13    TtfNameTable.NameRecord[] records = font.TtfTables.NameTable.GetNameRecordsByNameId(updateData.NameId);
14    TtfNameTable.NameRecord record;
15    // Update only the first matching record, preserving its platform and language.
16    // If the category is absent, use the identifiers of an existing name record.
17    if (records.Length == 0)
18    {
19        firstRecord ??= GetFirstExistingRecord(font.TtfTables.NameTable);
20        record = firstRecord;
21    }
22    else
23    {
24        record = records[0];
25    }
26
27    font.TtfTables.NameTable.AddName(updateData.NameId, (TtfNameTable.PlatformId)record.PlatformId,
28        record.PlatformSpecificId, record.LanguageId, updateData.StringData);
29}
30
31TtfNameTable.NameRecord GetFirstExistingRecord(TtfNameTable table)
32{
33    foreach (TtfNameTable.NameId nameId in Enum.GetValues<TtfNameTable.NameId>())
34    {
35        TtfNameTable.NameRecord[] records = table.GetNameRecordsByNameId(nameId);
36        if (records.Length != 0)
37            return records[0];
38    }
39
40    TtfNameTable.NameRecord[] allRecords = table.GetAllNameRecords();
41    if (allRecords.Length == 0)
42        throw new InvalidOperationException("The name table has no record to supply platform and language identifiers.");
43    return allRecords[0];
44}

テスト solution metadataexamples.csで見つけることができる「名前」テーブルを更新する他の例。