1

フォントを操作するコードを書く必要があります。私が始めるための主題への良い紹介はありますか?

4

1 に答える 1

4

What all developers should know about fontsに非常に優れた紹介があります。

ここに投稿をコピーしましたが、投稿の多くは特定のフォント部分が書かれていることと写真に依存しているため、上記のリンクを強くお勧めします.

私は当初、フォントを使用するのはかなり簡単だと思っていました。しかし、Windward Reports (当社の XML および SQL レポート システム) では、フォントを適切に処理するのにかなりの労力が費やされました。フォームに 1 行のテキストを配置する以上のことを行う場合は、詳細が重要になります。

フォントとグリフ では、フォントとは何でしょう? 基本的に、フォントは一連のグリフです。文字 A のような文字として考えられるものは、グリフです。フォントは、そのフォントのすべての文字のグリフのセットです。Helvetica フォントを取得すると、すべてのグリフが一方向に見えます。Times Roman フォントを使用すると、見た目が異なります。それぞれがそのフォントのグリフのセットです。

ここで、コード ページの概念を紹介する必要があります。コード ページは、文字番号から特定のグリフへのマッピングです。プログラムは元々、各文字をバイトとして格納していました。次に、アジア文字セットには DBCS システムがありました (一部の文字は 1 バイトで、一部は 2 バイトでした)。今日のプログラムはほとんどが Unicode を使用していますが、Web ページは最大 4 バイトまでのマルチバイト シーケンスである UTF-8 である傾向があります。

なぜエンコーディングを持ち出すのですか?各フォントには、フォントで使用されるコードページに応じて、文字番号 178 が非常に異なるグリフを返す可能性があるエンコーディングがあるためです。ほとんどのフォント ファイルは Unicode を使用しているため、そこに標準がありますが、多くのプログラムは依然として特定のコード ページを使用しており、そのページがフォントにマップされています。これは、ABC を表示し、フォントが Wingdings であるため、 が表示される場合に発生します。ポイント 1 は、使用するエンコーディングが、使用するフォントのエンコーディングと一致するか、マッピングされていることを確認する必要があるということです。

そして、それはさらに複雑になります。値が 0xE000 ~ 0xF8FF の文字は未定義です。各フォントは、それらを好きなものにすることができます (1 つの用途は、クリンゴン スクリプトを追加することです)。したがって、この範囲の値を持つ文字は、定義上、そのフォントを表示するために使用しているフォント ファイルに関連付けられています。これは、ほとんどの記号タイプのフォントが機能する方法です。

さて、あなたは Unicode を使用しており、フォント ファイルは Unicode を使用しており、それに文字列を渡すと… 文字列は空白で表示されます。どうしたの?フォント ファイルに特定の文字のグリフが含まれている必要はありません。Symbol フォントには ABC がありません。ヨーロッパとアメリカで使用されるほとんどのフォントには、中国語、日本語、または韓国語のグリフがありません。フォントにないグリフを使用してもエラーにはなりませんが、空白ではなく、何も表示されません (つまり、幅が 0 ポイント)。

コード ページに存在しないグリフを表示したい場合、古いコード ページのいずれかを使用している場合にも、同様の問題が発生する可能性があります。その場合、少なくともその文字については、別のコード ページでマップする必要があります (これは、Word がこのケースを処理するために使用した方法です)。

フォントファミリー フォントはいくつかの異なるクラスに分類されます。まず、プロポーショナル フォントとモノスペース フォントがあります。等幅フォントでは、すべての文字がまったく同じ幅です。また、高さは一貫しており、小文字はすべて大文字と同じ高さです。等幅フォントは読みにくいため、できるだけ避けてください。中国語の漢字はすべて同じ幅と高さを持っているため、アジアのフォントはほとんどすべて等幅であり、プロポーショナルは意味がありません。反対に、ヘブライ語とアラビア語はほぼ比例している必要があります。

次は、ストロークの最後に何かを取得するセリフ、最後に余分なものを取得しないサンセリフ、通常をはるかに超えた装飾、バーコードを含むランダムなものを含めることができるシンボルの書体です。グリフにマッピングされた文字コードの ASCII 番号と一致します。そして、これは西ヨーロッパのアルファベットです。

Fontmetrics さて、フォントの測定に取り掛かりますが、フォントごとに、そのほとんど (すべてではない) がグリフを測定しています。フォントに使用される標準的な測定値はポイントであり、ポイントが最初に何を意味したかについては多くの歴史がありますが、コンピューターの世界では 72 ポイント == 1 インチでした。また、ポイントの 20 分の 1 を表す twip が表示されることがあります。つまり、1440 twips == 1 インチです。そして、914400 EMU == 1 インチの EMU ができました (詳細はこちら)。点を扱う場合は、浮動小数点変数を使用する必要があります。通常、Twips は整数として問題なく、EMU は間違いなく問題ありません。

次に、フォントのポイント サイズです。これは完全に任意の数値です。古い CRT モニターの対角線のサイズのように考えてください。実際のサイズは予想に近いものでしたが、決してその数値ではありませんでした。ポイント サイズはレンダリングされるグリフのサイズを決定しますが、ページ上での特定の測定値はありません。

ここからが興味深いところです。fontmetrics です。まず、すべてをベースラインから測定する必要があります。フォントの他の部分からの作業は機能しません。大きな問題が発生します。そこから始めましょう。ベースラインより上に描画された最も高い部分はその上昇であり、ベースラインより下に描画された最も低い部分は下降であり、両方ともベースラインから測定されます。

次に、テキストの 2 行間のスペースがあります。これは、フォント デザイナーがそのフォントの適切な間隔を決定するためのフォント設定です。これはさまざまな方法で返される可能性があります。Windows はこれを次の行の上に配置した間隔と見なし、ベースラインからベースラインまでのメジャーを返しますが、Java はそれを次の行の前の行の下の間隔と見なし、この値だけを返します。このリーディングは、同様のシングル スペース テキストの行間に配置するスペースです。間隔が単一の間隔よりも大きい場合は、この値に追加します。

通常、これらの高さは、表示する文字列内のグリフの文字列ではなく、フォントに対して取得する必要があります。なんで?行が「we was wrox」である場合はどうでしょうか。アセンダーまたはディセンダーがない場合、その行は段落内の他の行の近くに配置され、奇妙に見えます。一部のテキストが大きい場合は、大きなアセント/ディセント/リーディング値を使用する必要があるため、すべてのフォントとポイント サイズも確認する必要があります。ただし、段落全体ではなく、より大きなテキストを持つ行のみ。繰り返しますが、これらはすべて、混合フォント/サイズを処理する唯一の方法であるベースラインから測定されます。

わかりました、高さには少し手間がかかりますが、かなり簡単ですが、幅 – これは非常に興味深いものです。興味深いというのは、すべてを適切に処理する必要があるということです。基本的に、固定幅フォントを除いて、各グリフの幅を合計しても、一緒にレンダリングされたすべてのグリフの幅と等しくなりません。ほとんどありません。なんで?いくつかの理由:

•カーニングとは、隣接する文字に基づいて文字を配置することです。そのため、tt がかなりオーバーラップしている間、AB は明確なままです。• ae が æ になり、ドイツ語の ss が ß になるなど、ラテン アルファベットの一部の文字の組み合わせが組み合わされます。• ヘブライ語とアラビア語のグリフは、同じ文字でも単語の先頭、中間、末尾のいずれにあるかによって異なります。また、アラビア語の場合、特に両端に使用されるグリフは、中央のグリフよりも幅が広くなる傾向があります。したがって、ﺺ の幅は文字列内の位置に依存します。◦ 双方向フォントには、以下に示す追加の問題があります。•インド語 (インド) のような複雑なスクリプトは、複数の文字から構成されている場所でグリフを変更します。したがって、3 文字の文字列は、1 ~ 3 グリフ幅の任意の文字列にすることができます。非常に簡単に言えば、完全にフォーマットされた完全な文字列をフィードする必要があります。実行しているプラ​​ットフォームが提供する fontmetrics API に接続して、文字列の長さを取得します。長さを決定するために文字列がメモリにレンダリングされるため、これは高価な呼び出しですが、正確な代替手段はありません。また、レンダリング時とまったく同じ測定設定を使用する必要があります。これらが一致しない場合はいつでも、人間の目で識別できるほど大きな違いがあることがわかりました。これについてコードをテストする最良の方法は、右揃えのテキストを確認することです。通常、レンダリング時に文字列の左端のベースライン位置を取得する必要があるため、長さを間違って計算すると表示されます。しかし、正確な代替手段はありません。また、レンダリング時とまったく同じ測定設定を使用する必要があります。これらが一致しない場合はいつでも、人間の目で識別できるほど大きな違いがあることがわかりました。これについてコードをテストする最良の方法は、右揃えのテキストを確認することです。通常、レンダリング時に文字列の左端のベースライン位置を取得する必要があるため、長さを間違って計算すると表示されます。しかし、正確な代替手段はありません。また、レンダリング時とまったく同じ測定設定を使用する必要があります。これらが一致しない場合はいつでも、人間の目で識別できるほど大きな違いがあることがわかりました。これについてコードをテストする最良の方法は、右揃えのテキストを確認することです。通常、レンダリング時に文字列の左端のベースライン位置を取得する必要があるため、長さを間違って計算すると表示されます。

双方向テキスト 最後に、双方向テキスト (アラビア語とヘブライ語) の問題があります。数字とラテン語の単語を除いて、双方向のテキストは右から左に表示されます。左から右に表示されます。したがって、右から左に読まれ、数字または一連のラテン語テキストでは、一番左のポイントにジャンプし、前のヘブライ語/アラビア語を完了した場所まで左から右に読み返され、次にラテン語の先頭にジャンプします/番号の部分に戻り、右から左に戻ります。

これらの切り替えがいつ行われるべきかについて、多くの研究が行われてきました。方向性の強いキャラ、弱いキャラ、方向性のないキャラがいます。これらの規則を正しく実装することを祈る必要はありません。なし。しかし、すべてが失われるわけではありません。Java や Windows を含むほぼすべてのプラットフォームには、読み取った順序で文字列を提供する API があり、ルールに従って正しくレンダリングされます。また、キャレットを 1 文字前後に移動する場合に、各文字がどこにあり、どの文字に移動する必要があるかを示す API もあります。

テキストに関係なく、すべてのフォント レンダリングとキャレットの移動にこの API を使用でき、複雑なスクリプトでも問題なく動作します。Bi-di や複雑なスクリプトを対象としていない場合、これから始めるのは少し面倒ですが、最終的にそこに行くつもりなら、それを使用して開始するのが最善です。コード。私を信じてください、あなたは本当に再構築する必要はありません (私は一度しなければなりませんでした – OW!)。

警告 Windows フォントを Linux または他のオペレーティング システムにコピーしないでください。フォントメトリクスはオフになる傾向があり、テキストはオフに見えます。TrueType が移植可能であると想定されているものはわかりませんが、実際には、Java がどこでもデバッグが一度書けるように、フォントはどこでも微調整される傾向があります。お使いのプラットフォーム用にフォントを最適化したベンダーからフォントを入手してください。

于 2010-12-04T19:02:33.053 に答える