フォント・データ用に非メモリ・マップドFlashを使用
このセクションでは、ほぼすべてのフォント・データを非マップドの外部Flashに配置できるようになる、非マップド・フォント・ストレージ・フォーマットの使用方法について説明します。 このストレージ・フォーマットにより、フォント・データ用にわずか10 KBの内部Flashを使用することで、1つのアプリケーションに数千の文字を保存できるようになります。
フォント・レイアウト
TouchGFXでは、ユーザのアプリケーションにコンパイルされるフォント用に、2つの異なるフォント・レイアウトがサポートされています。 使用するレイアウトは、TouchGFX Designerの設定(Configurations)タブで選択します。
Mapped storage formatはデフォルトのフォント・レイアウトで、フォントがメモリ・マップドFlash(内部Flash、または外部のQSPI Flashなど)に保存されるシステムではこれを使用する必要があります。
Unmapped storage formatは新しいフォント・レイアウトです。 大部分のフォント・データを非マップドFlashに保存することができます。 通常はSPI Flashに保存されますが、任意のタイプのストレージを使用できます。
マップド・ストレージ・フォーマット
マップド・ストレージ・フォーマットでは、フォント・データが2つのテーブルに保存されます。
1つ目のテーブルにはtouchgfx::GlyphNodeのアレイがあります。 ここには個々の文字のプロパティ(高さ、幅、Unicodeなど)が含まれています。
generated/fonts/src/Table_verdana_20_4bpp.cpp
FONT_TABLE_LOCATION_FLASH_PRAGMA
KEEP extern const touchgfx::GlyphNode glyphs_verdana_20_4bpp[] FONT_TABLE_LOCATION_FLASH_ATTRIBUTE =
{
    {     0, 0x0020,   0,   0,   0,   0,   7,   0,   0, 0x00 },
    {     0, 0x002C,   5,   7,   3,   1,   7,   0,   2, 0x00 },
    {    21, 0x0030,  11,  14,  14,   1,  13,   0,   0, 0x00 },
    {   105, 0x0032,  11,  14,  14,   1,  13,   0,   0, 0x00 },
    {   189, 0x0033,  11,  14,  14,   1,  13,   0,   0, 0x00 },
    {   273, 0x0034,  12,  14,  14,   0,  13,   0,   0, 0x00 },
    ...
}
2つ目のテーブル(大きなフォントでは複数ファイルに分割される)には、文字のピクセル・パターンが含まれています。
generated/fonts/src/Font_verdana_20_4bpp_0.cpp
FONT_GLYPH_LOCATION_FLASH_PRAGMA
KEEP extern const uint8_t unicodes_verdana_20_4bpp_0[] FONT_GLYPH_LOCATION_FLASH_ATTRIBUTE =
{
    // Unicode: [0x0020]
    // (Has no glyph data)
    // Unicode: [0x002C]
    0x00, 0x87, 0x04, 0x20, 0xFF, 0x03, 0x60, 0xBF, 0x00, 0xA0, 0x5F, 0x00, 0xE0, 0x0D, 0x00, 0xF3,
    0x07, 0x00, 0xF6, 0x01, 0x00,
    // Unicode: [0x0030]
    0x00, 0xA3, 0xFE, 0x9D, 0x01, 0x00, 0x40, 0xFF, 0x9B, 0xFC, 0x1D, 0x00, 0xD0, 0x4F, 0x00, 0x80,
    0x9F, 0x00, 0xF3, 0x0B, 0x00, 0x10, 0xEE, 0x00, 0xF7, 0x07, 0x00, 0x00, 0xFB, 0x03, 0xF9, 0x06,
    ...
}
テキストのレイアウト時には、GlyphNodesがTouchGFXエンジンによって使用されます。 ピクセルは描画時に、DMA2Dまたはソフトウェアルーチンによって読み取られます。
通常のLCDクラス(LCD16bppやLCD24bppなど)を使用するプラットフォームでは、これらのテーブルを内部Flashまたはメモリ・マップドの外部Flashに保存する必要があります。
LCD16bppSerialFlashを使用するプラットフォームでは、描画ソフトウェアで非マップド・シリアルFlashからピクセルパターンを読み取ることができますが、GlyphNodesが内部Flash内に存在しなければなりません(これは直接検索されます)。
このレイアウトでは、1文字につき内部Flashが14バイト使用されます。
非マップド・ストレージ・フォーマット
非マップド・ストレージ・フォーマットでは、フォント・データが3つのテーブルに分割されます。 マップド・ストレージ・レイアウトの2つのテーブルが再利用されますが、次に示す3つ目のテーブルが追加されます。
generated/fonts/src/Table_verdana_20_4bpp.cpp
FONT_SEARCHTABLE_LOCATION_FLASH_PRAGMA
KEEP extern const uint16_t unicodelist_verdana_20_4bpp[] FONT_SEARCHTABLE_LOCATION_FLASH_ATTRIBUTE =
{
    0x0020,
    0x002E,
    0x003F,
    0x004E,
    0x0054,
    ....
}
この3つ目のテーブルには、フォントを表すUnicodeが含まれています。
このフォント・レイアウトを使用する場合、3つ目のテーブルは内部Flash内に置く必要がありますが、他の2つのテーブルは外部Flashに移動できます。 これは大幅な節約になります。3つ目のテーブルでは、1文字に使用されるのは2バイトですが、GlyphNodeテーブルでは14バイト使用されるからです。 これにより内部Flashに必要な容量が軽減されます。
フォント・データ・リーダ
フォント・データが非マップドFlashに置かれると、マイクロコントローラは直接アクセスできなくなります。 そのため、Flashリーダ・オブジェクトをフォント・サブシステムに用意する必要があります。 このためのコードはTouchGFX Generatorによって自動的に生成されます。
TouchGFXConfiguration.cpp
static TouchGFXDataReader dataReader;
static LCD16bppSerialFlash display(dataReader);
static ApplicationFontProvider fontProvider;
static Texts texts;
static TouchGFXHAL hal(dma, display, tc, 240, 320);
void touchgfx_init()
{
  Bitmap::registerBitmapDatabase(BitmapDatabase::getInstance(), BitmapDatabase::getInstanceSize());
  TypedText::registerTexts(&texts);
  Texts::setLanguage(0);
  hal.setDataReader(&dataReader);
  fontProvider.setFlashReader(&dataReader);
...
Generatorを使用しない場合は、手動で生成する必要があります。
実際にデータをFlashから読み込むためには、TouchGFXDataReaderの機能の実装が必要です。
サマリ
フォント・データは2つまたは3つのテーブルに保存されます。 次の表に、Flashへの配置を示します。
| テーブル(サンプル名) | マップド・ストレージ・フォーマット | 非マップド・ストレージ・フォーマット | 
|---|---|---|
| GlyphNodes(glyphs_verdana_20_4bpp) | 内部 | 外部 | 
| ピクセル・データ(unicodes_verdana_20_4bpp_0) | 外部 | 外部 | 
| Unicode(unicodelist_verdana_20_4bpp) | 不使用 | 内部 | 
例
次に、新しいフォント・レイアウトを使用したアプリケーションのスクリーンショットを示します。
このアプリケーションは、MB1642Aディスプレイ・モジュール搭載のSTM32G071 Nucleoボードで実行されています。
このアプリケーションには、サイズが20、4bit/pixelの漢字4,000文字が含まれています。 このアプリケーションとデータは、STM32G071上で使用可能な128 KBのうち61 KBを占有します。 フォント・データは次のように配置されます(マイナーなオブジェクトを除く)。
| テーブル | 場所 | サイズ | 
|---|---|---|
| GlyphNodes | 外部SPI Flash | 57,372バイト | 
| ピクセルパターン | 外部SPI Flash | 3,116,296バイト | 
| Unicode リスト | 内部Flash | 8,000バイト | 
リンカ・スクリプトの更新
非マップド・フォント・レイアウトを正しく使用するには、テーブルが正しく配置されるようにリンカ・スクリプトを更新する必要があります。
STM32F746.ld
define symbol __ICFEDIT_region_ROM_start__ = 0x08000000;
define symbol __ICFEDIT_region_ROM_end__   = 0x0801FFFF;
define symbol __ICFEDIT_region_RAM_start__ = 0x20000000;
define symbol __ICFEDIT_region_RAM_end__   = 0x20008FFF;
define symbol __ICFEDIT_region_SERIAL_FLASH_start__ = 0x90000000;
define symbol __ICFEDIT_region_SERIAL_FLASH_end__   = 0x91000000;
place in ROM_region   { readonly };
place in RAM_region   { readwrite,
                        block CSTACK, block HEAP };
place in SERIAL_FLASH_region {section ExtFlashSection, section FontFlashSection };
このリンカ・スクリプトでは、ExtFlashSection(画像およびフォントのピクセル)とFontFlashSection(GlyphNodes)を両方とも外部Flashに配置しています。 その他の読み取り専用データはすべて内部Flash(ROM_region)にあります。


