フォント・キャッシュ
このセクションでは、フォント・キャッシュを使用してTouchGFXでバイナリ・フォントを処理する方法について説明します。
この記事の前に「バイナリ・フォント」をお読みください。
フォント・キャッシュ
バイナリ・フォントではフォント全体をメモリに読み込む必要があることを思い出してください。 大規模な中国語フォントなど、フォントの容量が大きい場合、これは望ましくない状態を生む可能性があります。
フォント・キャッシュを使用すると、アプリケーションは文字列の表示に必要な文字のみを外部メモリから読み込めるようになります。 つまり、アドレス指定可能なFlashまたはRAMにフォント全体を常駐させる必要がなくなり、もっと大きなファイル・システムに保存できるようになるのです。
下の図では、コンパイルされたフォントのFont2がフォント・キャッシュによって置き換えられています。 TouchGFXは、Font2を使用するテキストを描画するときに、フォント・テーブル内のCachedFont
オブジェクトへのポインタを検索します。 この特殊フォントはFontCacheオブジェクト内で文字をルックアップします。
CachedFontは、リンクされたフォント(上のFont2)へのポインタを使用して設定されます。 TouchGFXがCachedFontに特定の文字を要求すると、cachedFontはまず、置き換え対象として通常フォント(Font2)を検索します。 このフォントは空のフォントの場合がありますが、よく使用されるいくつかの文字の選択肢を含む「通常」フォントである可能性もあります。 フォントに必要な文字が含まれていない場合、CachedFontはFontCacheを調べて、ファイル・システムから文字が読み込まれていないかどうか確認します。
この方式では、キャッシュの必要がある文字の量が制限されます。通常フォントにすでにある文字をキャッシュする必要はないからです。
アプリケーション・コードでのフォント・キャッシュの使用
アプリケーションでCachedFontをインストールできるようにするには、FontCache、メモリ・バッファ、およびファイル・システム・リーダ・オブジェクトをあらかじめ作成する必要があります。
Screen1View.cpp
uint8_t fontdata[5120]; //Memory buffer for the font cache, 5Kb
FontCache fontCache;
CachedFont cachedFont; //Cached Font object
FileDataReader reader; //Filesystem reader object
FontCacheをバッファおよびリーダにリンクする必要があります。
Screen1View.cpp
//setup the font cache with buffer and size; and file reader object
fontCache.setMemory(fontdata, 5120);
fontCache.setReader(&reader);
これで、アプリケーションはフォント・キャッシュを設定し、CachedFontを初期化してTouchGFXに渡すことができます。
フォント・キャッシュでは、CachedFontオブジェクトを初期化するためにTextIdが必要です。 TextIdを使用して、CachedFontがポイントする必要があるフォントをルックアップします。 これによりユーザは、ディスプレイ上にあるテキストで使用されるフォントを確実に置き換えできます。
Screen1View.cpp
//initialize the cachedFont object to the font used by T_SINGLEUSEID1
TypedText text = TypedText(T_SINGLEUSEID1);
fontCache.initializeCachedFont(text, &cachedFont);
//replace the linked in font in TouchGFX with cachedFont
TypedTextDatabase::setFont(DEFAULT, &cachedFont);
上のコードはアプリケーションの任意の場所に配置できます。 キャッシュされたフォントが特定のビューのみで使用される場合、そのビューがコードを挿入するのに適した場所になります。
文字のキャッシュ
フォント・キャッシュはまだ空の状態です。 何か文字を表示できるようにするには、まず文字をフォント・キャッシュから読み取る必要があります。 このためには、Unicodeの配列(文字列)をフォント・キャッシュに渡します。 次の例では、T_SINGLEUSEID1から単純にテキストを渡しています。
Screen1View.cpp
//cache the glyphs used by the text T_SINGLEUSEID1
Unicode::UnicodeChar* str = const_cast<Unicode::UnicodeChar*>(text.getText());
bool b = fontCache.cacheString(text, str);
フォント・キャッシュは、str
配列で見つかった文字をリーダ・オブジェクトを介して読み込みます。 読み取られたUnicodeは、TextIdのtext
引数で使用されるフォントにリンクされます。
アプリケーションの役目は、リーダ・オブジェクトが正しいファイルから読み込むように設定することです。
リガチャのキャッシュ
表示する前に、Unicodeのシーケンスを他のUnicodeに変換する言語(アラビア語やデーヴァナーガリーなど)には、上記のメソッドは適しません。 キャッシュされるのは元のUnicodeで、変換後に表示されるUnicodeではないからです。 次のメソッドでは、所定のUnicodeを変換し、(変換後に)必要なUnicodeをキャッシュします。
Screen1View.cpp
//cache the glyphs used by the text T_SINGLEUSEID1 after conversion
Unicode::UnicodeChar* str = const_cast<Unicode::UnicodeChar*>(text.getText());
bool b = fontCache.cacheLigatures(cachedFont, text, str);
メモリ使用量
フォント・キャッシュでは、現在のメモリ使用量を計算できます。
Screen1View.cpp
touchgfx_printf("Memory usage %d\n", fontCache.getMemoryUsage());
GSUBテーブルのキャッシュ
一部のフォントでは、描画時にGSUBテーブルを使用します。 ただそれは、デーヴァナーガリー・フォントなど少数の東方言語のフォントのみです。 GSUBテーブルを使用すると、フォント・システムは他の「組み合わせ」文字用に、文字を並べ替えたり、文字のシーケンスを取り換えたりすることができます。
フォント・キャッシュはこのGSUBテーブルをファイル・システムから読み込むことができます。 これが読み込まれない場合、テキスト描画システムでGSUBテーブルを使用できなくなるので、フォントが正しく表示されません。
GSUBテーブルを読み込むには、キャッシュされたフォントを初期化するときに追加の引数を設定します。
Screen1View.cpp
//initialize the cachedFont and load the GSUB table
text = TypedText(T_SINGLEUSEID1);
fontCache.initializeCachedFont(text, &cachedFont, true);
フォント・ファイル・リーダの実装
上のサンプル・コードで使用されているFileDataReaderクラスは、TouchGFXに含まれていません。ユーザの使用するオペレーティング・システムに依存するものだからです。
次に、通常の"stdio"互換ファイル・システムの例を示します。
Screen1View.cpp
class FileDataReader : public FontDataReader
{
public:
virtual ~FileDataReader() { }
virtual void open()
{
fp = fopen("Font_verdana_20_4bpp.bin", "rb");
if (!fp)
{
touchgfx_printf("Unable to open font file!!!\n");
}
}
virtual void close()
{
fclose(fp);
}
virtual void setPosition(uint32_t position)
{
fseek(fp, position, SEEK_SET);
}
virtual void readData(void* out, uint32_t numberOfBytes)
{
fread(out, numberOfBytes, 1, fp);
}
private:
FILE* fp;
};
FileDataReaderクラスは、FontCache.hppにあるFontDataReaderインタフェースを実装します。
FontCache.hpp
class FontDataReader
{
public:
virtual ~FontDataReader() { }
virtual void open() = 0;
virtual void close() = 0;
virtual void setPosition(uint32_t position) = 0;
virtual void readData(void* out, uint32_t numberOfBytes) = 0;
};