주요 내용으로 건너뛰기

바이너리 폰트

이 섹션에서는 TouchGFX에서 바이너리 폰트를 사용하는 방법을 설명합니다. 첫 번째 섹션에서는 바이너리 폰트를 사용 시 이해하는 데 도움이 될 수 있는 TouchGFX의 폰트 및 텍스트 시스템에 대해 자세히 알아봅니다. 두 번째 섹션에서는 바이너리 폰트의 사용법에 대해 알아봅니다.

바이너리 폰트는 폰트 정보를 컴파일하여 애플리케이션(generated/fonts/src의 .cpp 파일)에 연결하는 기존 방식을 대체할 목적으로 사용할 수 있습니다. 바이너리 폰트의 가장 큰 이점은 용량이 더 작은 애플리케이션 이진 파일을 가져와서 사용하는 장치에 다양한 폰트 세트를 유연하게 제공할 수 있다는 점입니다. 예를 들어 중국에서 사용할 장치에는 중국어 폰트로, 그리고 일본에서 사용할 장치에는 일본어 폰트로 채울 수 있습니다. 단, 전체 바이너리 폰트를 RAM(또는 메모리 매핑 플래시)에 로드해야 하기 때문에 폰트 용량이 크면 문제가 될 수 있습니다.

일반적으로 폰트를 애플리케이션에 연결했을 때의 가장 큰 이점은 애플리케이션에 사용되는 텍스트와 타이포그래피가 업데이트되었을 때 항상 자동으로 애플리케이션에 추가된다는 점입니다. 따라서 사용법이 매우 쉽고 안전합니다. 하지만 폰트로 인해 애플리케이션의 크기가 커질 수 있다는 것이 단점입니다.

폰트 및 텍스트 시스템 클래스

TouchGFX는 기본 구성일 때 애플리케이션에서 사용되는 모든 텍스트와 폰트에 .cpp 파일을 생성합니다. 이 파일들은 컴파일된 후, 생성된 UI 및 애플리케이션 코드와 함께 애플리케이션에 연결됩니다.

예를 들어 TextArea가 포함된 UI에 텍스트를 표시할 경우 TextId를 사용해 해당 텍스트를 참조합니다. 이 TextId는 위젯이 텍스트에서 실제 문자를 찾는 데 사용됩니다. 그런 다음 위젯이 touchgfx::Texts 클래스 framework/include/touchgfx/Texts.hpp를 통해 텍스트에 액세스합니다.

텍스트 클래스에는 애플리케이션에서 사용되는 각 언어의 번역 테이블을 가리키는 포인터가 배열된 포인터 배열이 있습니다. 번역 테이블이란 원칙적으로 해당 언어에서 사용되는 모든 문자열을 모아 놓은 것을 말합니다.

텍스트를 특정 언어로 매핑하기

TouchGFX는 이 테이블을 통해 선택한 언어에서 지정된 텍스트를 찾습니다.

TouchGFX Designer에서 텍스트를 변경하거나 애플리케이션을 생성할 때마다 테이블이 다시 생성됩니다.

스크린에서 그리기 작업을 하려면 먼저 텍스트에 어떤 폰트를 사용하는지 알아야 합니다. 이러한 텍스트와 폰트 간 매핑은 TypedTextDatabase 클래스(generated/texts/include/texts/TypedTextDatabase.hpp)에서 제어합니다.

TouchGFX Designer의 Texts 탭에서 타이포그래피, 작성 방향(Left-to-right 또는 Right-to-left), 각 텍스트 정렬(Left, Right, Center)을 지정할 수 있습니다. 타이포그래피와 순서 및 정렬은 각 텍스트 번역마다 달라질 수 있습니다. 이렇게 설정한 정보는 각 언어별 테이블에 컴파일됩니다. 따라서 TouchGFX에서 특정 텍스트에 사용되는 폰트와 정렬 방식 및 작성 방식을 쉽게 알 수 있습니다.

언어별 타이포그래피 정보

위 그림에서 TypedTextData 테이블에는 세 개의 배열을 가리키는 포인터가 있는데, 애플리케이션에서 사용되는 각 언어마다 하나씩 총 세 개입니다. 각 배열에는 시스템 텍스트마다 하나씩 세 가지 요소가 있습니다. 각 요소는 폰트와 읽는 순서 및 정렬을 나타냅니다. 위 예에서는 세 가지 언어의 텍스트가 모두 동일한 폰트를 사용하고 있습니다. 에플리케이션에서 사용하는 폰트가 2개이기 때문에 폰트 테이블에도 2개의 포인터가 있습니다.

TouchGFX가 스크린에 텍스트를 그리기 위해서는 먼저 TypedTextData에서 지정된 텍스트를 찾습니다. 이 데이터에는 Excel 시트에 지정된 텍스트의 폰트 인덱스, 문자 방향(LTR/RTL), 그리고 가로 정렬(Left, Right, Center)이 포함되어 있습니다. TouchGFX는 TypedTextData(F1 또는 F2)의 폰트 인덱스를 사용해 올바른 텍스트 폰트를 찾습니다.

폰트가 애플리케이션으로 컴파일되면 이 모든 과정이 자동으로 일어납니다.

바이너리 폰트 사용

애플리케이션에서 사용하는 폰트와 문자가 많고 다양하면 애플리케이션의 크기가 엄청나게 커질 수 있습니다.

TouchGFX는 이러한 문제를 줄이기 위해 애플리케이션에서 바이너리 폰트를 사용하도록 지원합니다. 바이너리 폰트는 애플리케이션에 연결되지 않지만 애플리케이션과 별도로 파일로 저장됩니다. 이러한 파일들이 런타임에서 애플리케이션에서 로드되어 TouchGFX에 제공됩니다. 애플리케이션은 예를 들어 SD 카드 같은 외장 저장 장치에서 폰트를 로드하거나, 인터넷에서 폰트를 다운로드할 수 있습니다.

애플리케이션이 폰트를 로드하면 TouchGFX에게 바이너리 폰트를 폰트 시스템에 설치할지 여부를 물을 수 있습니다.

폰트 테이블에 바이너리 폰트 설치하기

위에서는 기본적으로 제공되는 Font2가 애플리케이션에서 로드한 Binaryfont로 바뀌었습니다. 따라서 연결된 Font2는 이제 TouchGFX에서 사용되지 않습니다.

바이너리 폰트를 생성하도록 폰트 변환 도구 구성하기

폰트 변환 도구는 바이너리 폰트를 생성하도록 구성해야 하는데, TouchGFX Designer에서 이를 쉽게 구성할 수 있습니다. 다음과 같이 Config 탭으로 이동하여 "Text Configuration"을 선택한 다음 "Binary font files"를 클릭합니다.

바이너리 폰트 선택하기

코드를 다시 생성하면 TouchGFX가 generated/fonts/bin/ 폴더에 바이너리 폰트를 생성하고 generated/fonts/src/에 저장된 일반 파일에서 폰트를 소거합니다.

수동 구성

TouchGFX Designer를 사용하지 않는 경우에도 바이너리 폰트를 생성할 수 있습니다. 프로젝트에서 application.config 파일의 text_configuration 구간에 있는 "binary_fonts"를 “yes”로 변경합니다.

application.config
  "text_configuration": {
"remap": "yes",
"a4": "yes",
"binary_translations": "no",
"binary_fonts": "yes",
"framebuffer_bpp": "16"
}

이제 다음 번에 자산을 생성하면 generated/fonts/bin 폴더에 바이너리 폰트가 생성됩니다.

바이너리 폰트 설치

TouchGFX에서 바이너리 폰트를 사용하려면 먼저 파일이나 기타 저장 장치에서 복사해야 합니다. 폰트는 RAM이나 QSPI 플래시(포인터를 통해 액세스 가능) 같이 주소 지정이 가능한 메모리에서 사용할 수 있어야 합니다.

애플리케이션이 바이너리 폰트를 메모리에 로드하면 메모리에서 폰트를 TouchGFX에 설치할 수 있습니다. 이후부터는 TouchGFX가 컴파일된 폰트가 아닌 바이너리 폰트를 사용하게 됩니다. 바이너리 폰트는 텍스트를 사용하기 전에 설치해야 하지만 부팅하자마자 설치할 필요는 없습니다. FrontApplication.cpp에서 FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap) 생성자를 사용하여 폰트를 설치할 수 있습니다. 무엇이든 그리기 작업을 하기 전에 이 생성자가 실행됩니다.

예를 들면 다음과 같습니다:

FrontendApplication.cpp
//read the file into this array in internal RAM
uint8_t fontdata[10000];

//binary font object using the data
BinaryFont bf;

FrontendApplication::FrontendApplication(Model& m, FrontendHeap& heap)
: FrontendApplicationBase(m, heap)
{
//read the binary font from a file
FILE* font = fopen("generated/fonts/bin/Font_verdana_20_4bpp.bin", "rb");
if (font)
{
//read data from the file
fread(fontdata, 1, 10000, font);
fclose(font);

//initialize BinaryFont object in bf using placement new
new (&bf) BinaryFont((const struct touchgfx::BinaryFontData*)fontdata);

//replace application font 'DEFAULT' with the binary font
TypedTextDatabase::setFont(DEFAULT, &bf); //verdana_20_4bpp
}
}

파일을 열고 데이터를 읽는 코드는 사용하는 파일 시스템과 운영 체제에 따라 다릅니다. 기본적으로 먼저 메모리에서 사용할 수 있는 폰트 데이터를 만들고 나서 포인터가 해당 데이터를 가리키도록 BinaryFont 객체를 초기화한 다음 마지막으로 BinaryFont 객체를 TouchGFX로 전달합니다.

그러면 setFont를 호출한 후 TouchGFX는 스크린에 텍스트를 그리기 위해 바이너리 폰트를 사용할 것입니다.

폰트 리셋하기

간혹 바이너리 폰트를 사용하다가 애플리케이션으로 컴파일된 원본 폰트로 돌아가야 하는 경우도 있는데, 예를 들면 언어를 변경하면서 기본 폰트를 사용하고 싶을 때가 그렇습니다. 이때는 TypedTextDatabase에서 다음과 같이 resetFont() 함수를 사용하면 폰트 포인터가 기본적으로 제공되는 폰트를 가리키도록 리셋됩니다.

//reset to original font
TypedTextDatabase::resetFont(DEFAULT);

위 함수를 호출하면 애플리케이션이 새 폰트를 할당하거나, 그 밖에 다른 목적으로 바이너리 폰트에서 차지하고 있는 메모리를 재사용할 수 있게 됩니다.