テキストとフォント
フォントとテキストは、現代のグラフィカル・ユーザ・インタフェースの非常に重要な要素です。 アプリケーションがサポートするすべての言語で、高品質でなめらかなテキストを表示できるようにすることはとても重要です。
TouchGFXでは、TouchGFX DesignerのTexts Viewによって、テキストとタイポグラフィの作成および変更をサポートしています。 TouchGFX Designerは、テキストとタイポグラフィの設定をassets/texts/texts.xlsx
にあるスプレッドシートに出力します。 このスプレッドシートはフォント・ファイルと一緒に、フォントおよびテキスト変換ツールに供給され、これによって生成済みのC++コード・ファイルが作成され、TouchGFXが描画できるようになります。
この記事では、テキストおよびフォント変換ツールを紹介し、コードとTouchGFX Designerを通じてアプリケーション内で生成済みテキストを使用する方法について説明します。
テキストとタイポグラフィ
TouchGFXアプリケーションのテキスト、翻訳、タイポグラフィは、assets/texts/texts.xlsx
にあるスプレッドシートに出力されます。 このスプレッドシートは2つのシートで構成されます。 1つはアプリケーション内で使用されるタイポグラフィを定義し、もう1つはテキストとそのすべての翻訳を定義するものです。 このスプレッドシートは一般には「テキスト・データベース」と呼ばれます。
タイポグラフィは、TouchGFX DesignerではTexts Viewを使用して編集します。これによりテキストと翻訳をリアルタイムで編集して処理できます。 texts.xlsxスプレッドシート内で、タイポグラフィとテキストを直接編集することもできますが、 この方法は一般的に(少なくとも開発中には)お勧めできません。 ただし、翻訳用に外部リソースを使用する場合は、TouchGFX Designerを使用しないで、スプレッドシートを共有する方が処理が容易になる可能性があります。 開発中にスプレッドシートを編集する場合は、編集時にはTouchGFX Designerを閉じる必要があります。開いているとtexts.xlsxファイルがロックされるからです。
Further reading
Note
テキスト・コンバータ
テキスト・コンバータは、テキスト・データベース内の情報を、TouchGFXアプリケーションで使用される内部C++フォーマットに変換するツールです。 このツールは、ビルド・ツールチェーンの統合パートで、シミュレータの構築時に自動的に実行されます。 前回の構築以降にテキスト・データベースの更新がなかった場合、テキスト・コンバータは実行されません。
Note
generated/texts/
です。テキスト・コンバータは、テキスト・データベース内の指定されたすべてのテキストを、TouchGFXで使用されるテキスト・フォーマットに変換します。 このフォーマットはTypedText
と呼ばれるオブジェクトでラップされます。 TouchGFXのTypedText
は、テキスト・コンテンツそのものとテキストのタイポグラフィを組み合わせた実態です。 タイポグラフィには、テキストのフォントとフォント・サイズ、およびフォントのグリフのアンチエイリアシング(なめらか処理)で使用されるピクセルあたりビット数(bpp)が含まれます。
テキスト・コンバータは、generated/texts/include/texts/TextKeysAndLanguages.hpp
というファイルを生成します。 このファイルには、テキスト・データベース内のすべてのテキストを参照するenum(列挙型)のTEXTS
が含まれています。
enum内のすべてのエントリは、テキスト・データベースの各行に示されたテキストIDから生成されますが、先頭にT_が付き、大文字に変換されます。 これらの列挙値は、アプリケーション内でTypedTextを初期化するために使用されます。
TextKeysAndLanguages.hpp
には、テキスト・データベース内に存在するすべての言語を指定するenumのLANGUAGES
も含まれています。 命名方法はテキスト・データベース内の言語の列と同じです。
generated/texts/include/texts/TextKeysAndLanguages.hpp
/* DO NOT EDIT THIS FILE */
/* This file is autogenerated by the text-database code generator */
#ifndef TEXT_KEYS_AND_LANGUAGES_HPP
#define TEXT_KEYS_AND_LANGUAGES_HPP
typedef enum {
GB,
DE,
NUMBER_OF_LANGUAGES
} LANGUAGES;
typedef enum {
T_TEMPERATURE_READOUT,
T_TEMPERATURE_HEADLINE,
NUMBER_OF_TEXT_KEYS
} TEXTS;
#endif /* TEXT_KEYS_AND_LANGUAGES_HPP */
フォント・コンバータ
フォント・コンバータは、フォント・ファイル内の情報とテキスト・データベース内の情報を結合し、アプリケーションで必要とされる文字を生成するツールです。 出力フォーマットは、TouchGFXアプリケーションで使用される内部C++フォーマットです。 このツールは、ビルド・ツールチェーンの統合パートで、シミュレータの構築時に自動的に実行されます。
フォント・コンバータは以下のフォーマットが利用できます。
- TrueType(.ttf)
- OpenType(.otf)
- Glyph Bitmap Distribution Format(.bdf)
フォントは単純にassets/fonts/
フォルダ内に配置され、TouchGFX Designerで参照できるようになります(TouchGFX Designerの実行中にフォントが追加された場合、再起動して使用可能なフォントを更新する必要があります)。
TouchGFX Designerでは、Windowsにインストールされたフォントも使用することができます。これらのフォントを選択すると、自動的にassets/fonts/
フォルダに追加されます。
フォント・コンバータは、提供されたフォント内のカーニング情報を使用することでカーンニングをサポートします。
Note
文字メモリ最適化
TouchGFXはメモリ消費量を少なくするために最適化されています。 特定のタイポグラフィに使用される文字の解析によって、生成される文字数(内部C++フォーマット)は、アプリケーションで実際に使用される文字数まで最小化されます。
テキストのメモリ消費量も、共通の接尾文字を使用するテキストを圧縮することで最適化されます。このためには、Text Configurationでテキストの再配置を行うオプション(Remap texts)を有効にします。
ワイルドカード
実行時の値をテキストの一部として使用できます。 これはテキスト内でワイルドカードを使用することで可能になります。 これらは<*>
という所定のフォーマットで指定され、*は変換結果のテキストには含まれないオプションの補助テキストを表しています。 1つのテキスト内で最大2つのワイルドカードを使用できます。
特定のテキストのすべての翻訳に、同じ数のワイルドカードを含める必要があります。 ワイルドカードの値は、実行時にアプリケーションのC++コードで挿入されます。
ワイルドカードの使用例: The temperature is <insert_temperature>°
注意すべき詳細事項の1つとして、文字メモリ最適化(前のセクションを参照)のために、特定のタイポグラフィを持つテキスト内では、そのタイポグラフィ用に生成された文字のみが使用されることがあります。 フォント・ジェネレータに特定の文字を強制的に含めるには、各タイポグラフィで"Wildcard Characters"および"Character Ranges"を使用します。
ワイルドカードのフォーマット<*>
は、\<not a wildcard\>のように、バックスラッシュ表記を使用することでエスケープできます。 この例の結果として、アプリケーション内では"<not a wildcard><not a wildcard>"という文字テキストが使用されることになります。
TouchGFX Designerでのワイルドカードの使用
TouchGFX Designerでは、ワイルドカードを通常のテキスト・エリアに追加できます。 事実上、これによってTextAreaウィジェットが、これまでTextAreaWithOneWildcard / TextAreaWithTwoWildcardsウィジェットが対応していた機能を網羅することになりますが、TouchGFXでのコード生成方法に変更はありません。
TouchGFX Designerでワイルドカードをテキスト・エリアに追加するには、通常の構文<*>
を使用するか、選択したテキスト・エリアのプロパティでAdd Wildcardボタンを単純にクリックします。 よく使用される例として、The temperature is °と表示されているテキスト・エリアに、読み取った温度を追加することがあります。 この例では、屋外温度の読取りに使用できます。 ここでは、静的な数値を表示するだけでなく、読み取った温度に応じて更新されるようにワイルドカードを挿入してみます。 ワイルドカードは、テキスト内のキャレット(挿入記号)の現在の位置に追加されます。
これでプロパティ内のテキスト表示はThe temperature is <value>°になり、キャンバス上のテキスト表示はThe temperature is °になります。
特定のワイルドカードを設定するには、対応するWildcardボタン(この例ではWildcard 1)をクリックします。これにより、追加したワイルドカードの編集が可能になります。
ここでワイルドカードの更新方法を選択できます。 このためには、事前定義されたリソース・テキストを使用するか、実行時に動的に作成されたテキストを使用します。 どちらの場合も、実行時にテキストを更新できます。 後者では、ダイナミック・テキストを保存するためのワイルドカード・バッファが必要になります。 このバッファを作成するには、Wildcard Bufferのチェック・マークをオンにします。 この例では、バッファのサイズ(文字数)を指定する必要もあります。 メモリを効率化するには、指定するサイズを、実際に必要なテキスト・サイズとできる限り近づける必要があります。 文字列の終了を示すために、余分なスペースを1つ追加することを忘れないでください(‘\0’)。
ワイルドカードの初期値を設定することもできます。これにより、温度の読取りによって最終的にテキスト・エリアがどのような表示になるのか確認できます。 初期値を設定すると、ハード・コードされたシングル・ユース・テキストがテキスト・データベース内に作成されるか、ワイルドカード・バッファの使用を選択した場合には、そのシングル・ユース・テキストがワイルドカード・バッファ内に挿入されます。
ユーザ・コードでのワイルドカードの使用
以下の例に示すように、ワイルドカードはユーザ・コードを使用して追加および更新することもできます。この例ではUnicode::UnicodeChar
配列が管理され更新されています。
gui/include/gui/some_screen/SomeView.hpp
#include <touchgfx/widgets/TextAreaWithWildcard.hpp>
...
class SomeView : public View<SomePresenter>
{
TextAreaWithOneWildcard txt;
Unicode::UnicodeChar txtBuffer[10];
}
gui/src/some_screen/SomeView.cpp
#include <texts/TextKeysAndLanguages.hpp>
#include <touchgfx/Color.hpp>
void SomeView::setupScreen()
{
txt.setTypedText(TypedText(T_TEMPERATURE_READOUT));
txt.setXY(10, 20);
txt.setColor(Color::getColorFrom24BitRGB(0xFF, 0xFF, 0xFF))
txt.setWildcard(txtBuffer);
add(txt);
updateTxt(5);
}
void SomeView::updateTxt(int newValue)
{
Unicode::snprintf(txtBuffer, 10, "%d", newValue);
txt.invalidate();
}
テキストの配置
TouchGFXのすべてのウィジェットと同様に、スクリーン上にテキスト・エリアを配置するには、位置(XおよびY)と寸法(幅および高さ)を指定します。 これはTouchGFX Designerのウィジェットのプロパティで簡単に実行できますが、TouchGFX Designerにおけるテキストの描画は、TouchGFXでテキストを描画する方法と比べると、必ずしも100%正確ではありません。
さらに、テキストを処理するときには、このセクションで説明するような注意すべき詳細事項やその可能性がいくつかあります。
アラインメント
テキスト・エリア内のテキストは、テキスト・データベース内の選択したテキスト・エントリに対して指定されているアラインメントに従って配置されます。 テキストはテキスト・エリアの領域を基準にして配置されます。 次のスクリーンショットでは、テキスト・エリアの領域が青色でハイライト表示されています。
これらの設定はTouchGFX DesignerのTexts Viewで行うことができます。
テキスト・エリアの正しい幅と高さの設定
テキスト・エリアでは、現在選択されているテキストに応じて幅と高さを調整することができます。 このためには、TextArea::resizeToCurrentText()
メソッドを読み出して実行します。
Note
resizeToCurrentText()
は、幅と高さが設定されていない場合に、新しいTypedTextによってTextAreaをインスタンス化すると自動的に呼び出されます。中央揃え / 右詰めのテキストを使用する場合は、固定領域内でテキストを中央揃え / 右詰めにする必要があるので、幅や高さのサイズ変更をしないことがほとんどです。 この場合は、幅と高さを手動で設定します。 このためには、TextArea::setPosition(x, y, width, height)
、TextArea::setWidth(width)
およびTextArea::setHeight(height)
を呼び出して実行します。
幅または高さ(あるいは両方)が小さすぎてテキストに適合しない場合には、下に示すように領域に合わせてテキストが切り取られます。
テキスト・エリアの正しいXおよびYの設定
テキスト・エリアを正しいXY位置に配置するには、大きな文字の表示を可能にするために、使用するフォントには文字の上に少し余白が設けられることに注意する必要があります。 このために、左上隅のY位置に従ってテキスト・エリアを配置することが少し難しくなります。テキスト上部のスペースの正確な大きさがわからないからです。 テキストを配置する1つの方法は、ほぼ間違いないと思われる位置を指定し、その後シミュレータで配置を調べて位置を微調整することです。 ほとんどの場合この方法は非常に単純な作業ですが、フォントまたはフォント・サイズを後で変更する場合には再実行の必要があります。
もっと堅実な方法として、テキスト・ベースラインの使用があります。 ベースラインとは、ほとんどの文字の「お尻が揃う」位置を示すラインで、その下にディセンダ(pやjなどの文字)が延びます。
ベースラインを設定するには、TextArea::setBaselineY(y)
またはTextArea::setXBaselineY(x, y)
を使用します。 これらのメソッドでは、テキスト・エリアの左上隅を指定するのではなく、最初のテキスト行のベースラインを指定します。 これによりフォント・サイズとスペースの大きさが考慮され、それに応じてテキスト・エリアのY位置が設定されます。
ベースライン機能はTouchGFX Designerでは使用できません。TextAreaウィジェットの配置はTouchGFX Designerのキャンバスで簡単に実行できるからです。このため、ベースライン機能はユーザ・コードでのみ使用されます。
Note
setBaselineY
を呼び出す必要があることにも注意してください。長いテキスト行の自動ラップ
場合によっては、テキスト・エリアに非常に長いテキストを含むことがあります。 デフォルトでは、こうしたテキストは単純に1行で記述され、テキスト・エリア内に収まらないテキストはすべて単純に切り取られます。 テキストをスペースの位置でラップして(折り返して)リフローさせ、複数の行で表示する必要がある場合は、単純に以下を呼び出します。
myTextArea.setWideTextAction(WIDE_TEXT_WORDWRAP); // Default is WIDE_TEXT_NONE
使用可能なWide Text Action
WIDE_TEXT_NONE
: 何も実行せず、テキスト・エリアの幅を越えて延びる文字の半ばで単純にテキストを切ります。WIDE_TEXT_WORDWRAP
:: 単語間でラップし、任意の場所に省略記号を表示します("Very long t...")。WIDE_TEXT_WORDWRAP_ELLIPSIS_AFTER_SPACE
: 単語間でラップし、スペースの後の任意の場所に省略記号を表示します("Very long ...")。WIDE_TEXT_CHARWRAP
: 任意の2文字の間でラップし、任意の場所に省略記号を表示します(中国語で使用)。WIDE_TEXT_CHARWRAP_DOUBLE_ELLIPSIS
: 任意の2文字の間でラップし、任意の場所に省略記号を二重に表示します(中国語で使用)。
Further reading
おそらくこれによってテキスト・エリアには縦方向のスペースが多く必要になります。 スペースを増やすには、Designerでテキスト・エリアの高さを増すか、次のようなユーザ・コードを使用します。
myTextArea.setWidth(200);
myTextArea.resizeHeightToCurrentText(); // Will set height by wrapping text at 200px long lines
myTextArea.invalidate();
テキスト・エリアのサイズを小さくする場合には、myTextArea
のサイズを変更する前にmyTextArea.invalidate()
を呼び出すことを忘れないでください。 そうしないと、新しい小さくなったテキスト・エリアではカバーされない古いテキスト・エリアの一部が表示されたままになるからです。
言語の切替え
TouchGFXは多言語インタフェースをサポートしています。 インタフェースで使用されている現在の言語は、スタティック・メソッドTexts::setLanguage
を呼び出すことで変更できます。
Texts::setLanguage(GB);
GB値は、The Text Converterセクションの例に示すように、TextKeysAndLanguages.hpp
のLANGUAGES
enum(列挙型)の中にあります。
この呼出しの後、テキストを表示するすべてのウィジェットを無効化(または単純にスクリーン全体を無効化)すると、新しく選択した言語でテキストが表示されます。
TouchGFX Designerでの操作
言語間を切り替えて、すべての翻訳をテストできます。 この操作はConfig ViewのGeneralセクションで行います。 ここでは単純に、Selected Languageを変更してアプリケーションの起動言語を変更します。 Config Viewで選択可能にするには、言語を作成して翻訳する必要があります。