ビットマップ・フォントの圧縮
TouchGFXバージョン4.25から、ビットマップ・フォントの圧縮がサポートされています。
ビットマップ・フォントの圧縮機能により、4 BPPのビットマップ・フォントを圧縮できます。 目的は、レンダリング・パフォーマンスを維持しながらフォント・データのサイズを削減することです。
Designerでは非常に単純な方法でフォントの圧縮が可能になります。 Designerで、タイポグラフィの[Bpp]として[4 - compressed]を選択するだけです。
これによって2つのタイプのアプリケーションにメリットがもたらされます。 数千の文字(漢字など)を使用するアプリケーションと、非常に大きな文字を使用するアプリケーションです。 これらのアプリケーションには大きなメリットがもたらされます。 一方、サイズが20の英文字のみを使用するアプリケーションにはあまりメリットがありません。フォント・データがそもそも大きくないからです。
圧縮率は文字のサイズ(フォント・サイズ)によって決まります。 小さいフォントの圧縮率は大きいフォントより劣ります。 元のサイズの30% ~ 70%の圧縮率を期待できます。
描画前に文字がキャッシュ・バッファへ解凍されます。 文字がキャッシュ内に存在しない場合は、レンダリングの前に解凍を行う手間が生じます。 使用される圧縮アルゴリズム(ランレングス圧縮)は解凍が非常に簡単なタイプなので、通常、問題は発生しません。 文字がすでにキャッシュ内に存在する場合、レンダリングのパフォーマンスが通常より少し上がります。SRAMからのレンダリングの方が外部Flashからより高速だからです。 キャッシュ・サイズはDesignerで設定できます。 以下を参照してください。
同じ文字を何度も繰り返して描画する場合(テキスト内の繰り返しであったり、アニメーションやスクロールの一部としてテキストを再描画する場合)、キャッシュによって解凍にかかる時間を無くせることが多くあります。
Note
キャッシュの大きさが十分でない場合、アプリケーションが停止します。
[こちら](#font-configuration)の手順を参照してください。
プラットフォームでハードウェア・アクセラレーションによる描画が提供されている場合、圧縮されたフォントにもこれは利用できます。
圧縮されたフォントに替わるものとして、ベクタ・フォントがあります。 複数サイズのフォントが使用される場合、通常これらは圧縮されたフォントよりも小さくなりますが、パフォーマンスへのインパクトは大きくなります。
ベクタ・フォントの詳細については、こちらを参照してください。
パフォーマンス
このセクションでは、多数の漢字を使用するアプリケーションと大きな数字を使用するアプリケーションを検討します。
最初の例として、NotoSansCJKsc-Black.otfを使用してサイズ28のフォントを作成します。 0x4E00から0x5E00までの範囲の文字を含めます(テキストではそれ以外にいくつか追加で使用します)。 これにより4165文字が提供されます。 もちろん実際の中国語アプリケーションにはさらに多くの文字が含まれています。
アプリケーションが24文字のテキストを表示します。
2つ目のアプリケーションは、Verdanaをサイズ40とサイズ140で使用します。
フォント・データのサイズと文字の描画パフォーマンスを確認します。
フォント・データのサイズ
下の表はフォント・データのサイズ(バイト数)を示しています。
フォント | サイズ | 文字 | 非圧縮サイズ | 圧縮サイズ | 削減量 | 圧縮率 |
---|---|---|---|---|---|---|
NotoSansCJKsc-Black.otf | 28 | 4,116 | 1,568,599 | 917,170 | 651,429 | 1.7 |
Verdana.ttf | 40 | 95 | 27,369 | 12,789 | 14,580 | 2.1 |
Verdana.ttf | 140 | 11 | 40,408 | 8,211 | 32,197 | 4.9 |
漢字の圧縮によって500KB以上節約されていることがわかります。 これにより十分な大きさの外部Flashサイズが削減され、部品コストも削減できます。
Verdanaフォントの圧縮では、圧縮率は高いのに同様のバイト数が削減されていませんでした。 文字数が非常に少ないことが主な理由です。
2つのVerdanaフォントの圧縮サイズの合計は22KBを下回っています。 つまり、このフォント・データは非常に小さなデバイスの内部Flashに収まるのです。
ベクタ・フォントとしてNotoフォントを生成すると、フォント・データのサイズは1,509,236バイトになります。 これは非圧縮のフォント・サイズをわずかに下回りますが、圧縮されたビットマップ・フォントよりも大きくなります。 ベクタ・フォントの使用によってサイズを大きく節約できるのは、ベクタ・フォントを複数のサイズで使用する場合です。すべてのサイズのフォントでデータがシェアされるからです。
レンダリング
次に、圧縮された文字のレンダリングのパフォーマンスを確認します。 キャッシュ・サイズの重要性がわかります。 アプリケーションで同じ文字が繰り返し描画され、キャッシュがそれらを保持できるだけ十分に大きい場合、パフォーマンスは非圧縮のフォントとほとんど同じか、上回る場合もあります。
最初に取り上げるのは中国語のアプリケーションで、キャッシュのサイズは10,000バイトです。 使用されるすべての文字を保持するのに十分なサイズです。
バックグラウンド画像を含む全画面の再描画にかかるレンダリング時間を測定します。
テスト | キャッシュ・サイズ | レンダリング時間/ms |
---|---|---|
バックグラウンド画像 | - | 5.28 ms |
非圧縮のNoto | - | 7.57 ms |
圧縮されたNoto | 10000 | 7.55 ms |
圧縮されたNoto | 5000 | 9.41 ms |
圧縮されたNoto | 2000 | 9.42 ms |
表示されるすべての文字を保持するためのキャッシュの容量は、およそ8000バイトです。 キャッシュがこれより大きく、最初のフレームで文字が解凍された場合、それ以降のすべてのフレームで再び解凍することなくレンダリングを実行できます。 キャッシュがもっと小さい(5,000または2,000バイト)場合は、繰り返し解凍する必要があります。すべての文字を保持できるだけの大きさがキャッシュにないからです。 パフォーマンスは低くなりますが、まだ使える範囲です。
では、2つ目のアプリケーションを見てみます。 今回はすべてのフレームで大きな数字のみが再描画されます。 この数字はそれぞれ約4,000バイトなので、10,000バイトのキャッシュは2つの数字を保持するのに十分な大きさです。 たとえば5000バイトのキャッシュであれば1文字しか保持できないので、繰り返し解凍する必要があります。
テスト | キャッシュ・サイズ | レンダリング時間/ms |
---|---|---|
バックグラウンド画像 | - | 1.44 ms |
非圧縮のVerdana | - | 2.46 ms |
圧縮されたVerdana | 10000 | 2.45 ms |
圧縮されたVerdana | 5000 | 3.57 ms |
この場合も、キャッシュの大きさが十分であればパフォーマンスは変わりませんが、そうでなければペナルティが生じます。
最後の例として、多数の「A」という文字のみを表示するもっと人工的なアプリケーションを使用します。
テスト | キャッシュ・サイズ | レンダリング時間/ms |
---|---|---|
バックグラウンド画像 | - | 5.19 ms |
非圧縮のVerdana | - | 16.51 ms |
圧縮されたVerdana | 10000 | 16.45 ms |
圧縮されたVerdana | 1000 | 16.46 ms |
すべての設定でパフォーマンスは同じです。 1つの「A」という文字のみを描画するので、非常に小さいキャッシュで十分だからです。
フレーム内に描画された複数の一意の文字を保持する場合、キャッシュには十分な大きさが必要ですが、 この場合は「A」のみです。
まとめ
要するに、フレーム内に描画された文字がキャッシュに保持されていれば、圧縮されたフォントのパフォーマンスは非圧縮のフォントと同じになります。 つまり、キャッシュが十分に大きければ、圧縮されたフォントをアニメーションやテキストのスクロールに使用できます。
キャッシュの大きさが十分でない場合でも、文字の解凍によるパフォーマンスへのインパクトは大きくありません。 つまり、小さなキャッシュでスタティック・テキストに対して圧縮されたフォントを使用しても、大きなパフォーマンス問題は起こりません。
設定
概要で触れたように、フォントの圧縮は、Designerにおいて個々のタイポグラフィで選択することで有効にできます。 必要な解凍コードはアプリケーションによって自動的にインクルードされます。
キャッシュ・サイズ
キャッシュ・サイズはDesignerで設定できます。 [Config]タブで[Text Configuration]を選択します。
最も大きい文字の圧縮データに必要なサイズよりキャッシュが小さい場合、TouchGFX Designerがログでエラーを報告します。
報告された数値より大きくなるようにフォント・キャッシュを変更します。
フォント・ファイルには、フォント内のすべての文字を描画するための必要最小限のキャッシュ・サイズが示されます。 この情報は、TouchGFX/generated/fonts/src/Table_xxx.cppファイルにあります。
上に示すように、サイズ140のVerdanaフォントの場合、すべての文字を描画するために4025バイト以上のキャッシュが必要です。
キャッシュの失敗
描画される文字を保持できるだけキャッシュが十分に大きくない場合、アプリケーションが停止します。 アプリケーションは、関数CompressedFontCache::unableToCache(const GlyphNode* glyphNode, int byteSize)を呼び出しますが、返されることはありません。
このエラーが発生するのは、生成されたファイルをユーザが手動で変更した場合のみです。
制限
圧縮された4 Bppと非圧縮の4 Bppの両方で同じフォントを使用することはできません。