주요 내용으로 건너뛰기

벡터 글꼴

TouchGFX는 버전 4.23부터 벡터 형식의 글꼴 사용을 지원합니다. 한 글꼴은 모든 크기에서 글꼴 데이터를 공유하므로 글꼴을 벡터 형식으로 저장하면 글꼴 데이터의 크기를 줄일 수 있습니다. 이는 한 글꼴의 모든 크기에 해당 크기 글리프의 전용 비트맵이 있는 비트맵 글꼴과 대비됩니다.

TextArea, ButtonWithLabel과 같은 위젯을 사용하는 일반 비트맵 글꼴과 같이 사용자 인터페이스에서 벡터 글꼴을 사용합니다.

벡터 형식 글꼴을 사용하려면 STM32CubeMX의 플랫폼에서 벡터 글꼴 기능을 활성화해야 합니다.

벡터 글꼴은 16bpp, 24bpp 또는 32bpp 프레임 버퍼에서만 지원됩니다.

벡터 글꼴이란

벡터 글꼴은 개별 글자가 곡선과 직선으로 구성되어 있는 글꼴입니다. 이러한 곡선과 직선은 다양한 크기의 글리프를 만들기 위해 크기를 늘리거나 줄일 수 있습니다. TouchGFX에서 일반적으로 사용하는 모든 글꼴은 벡터 글꼴(예: TrueType 또는 OpenType 글꼴)입니다. 글꼴 설명의 곡선과 직선은 TouchGFX Designer가 애셋을 생성할 때 TouchGFX Font Converter에 의해 여러 작은 비트맵으로 변환됩니다.

벡터 글꼴은 TouchGFX Designer에서 정의한 타이포그래피를 기반으로 비트맵으로 변환됩니다. 예를 들어 애플리케이션은 Large 및 Small 타이포그래피를 사용할 수 있습니다. Large는 30포인트 Verdana를 기반으로 하고 Small은 20포인트 Verdana를 기반으로 할 수 있습니다. 애플리케이션이 이러한 타이포그래피에서 A~Z 및 a~z 글리프를 사용한다고 가정하는 경우 각 타이포그래피에 52개의 글리프가 있지만 각 글자에 대해 두 개의 비트맵이 있으므로 애플리케이션에는 104개의 비트맵이 포함됩니다. 하나는 30포인트 비트맵이고 다른 하나는 20포인트 비트맵입니다.

특정 글리프에 대한 벡터 정의를 유지하고 글리프의 비트맵을 생성하지 않으므로 벡터 글꼴은 각기 다릅니다. 이 벡터 글꼴은 대신 대상 애플리케이션에 한 번만 포함됩니다. 요구되는 두 개의 타이포그래피를 생성하기 위해 필요한 유일한 외부 데이터는 각기 다른 두 가지 스케일링 계수입니다. 하나는 벡터 정의를 30포인트로 스케일하기 위한 것이고 하나는 벡터 정의를 20포인트로 스케일하기 위한 것입니다.

결과적으로 예제 애플리케이션에 예를 들어 40포인트 Verdana와 같은 또 다른 타이포그래피를 추가하는 경우 플래시 요구사항은 크게 증가하지 않습니다.

예제

예를 들자면 TrueType 글꼴 Verdana의 "G"에 대한 벡터 정의는 170바이트입니다.

이 글리프를 나타내는 비트맵의 크기는 사용되는 bpp와 글리프 크기에 의해 결정됩니다. 아래 표는 4pp의 다양한 글리프 크기의 "G" 비트맵 크기를 보여줍니다.

글꼴 크기G 글리프 크기/픽셀비트맵 크기/바이트
2014 x 1498
3021 x 22242
4027 x 32448
총계788

글꼴 크기 20포인트의 비트맵 크기는 "G"의 벡터 정의보다 작지만 30포인트만 되어도 벡터 정의가 비트맵 크기보다 작아집니다. Verdana 글꼴을 세 가지 크기로 사용하는 경우 비트맵으로 788바이트를 사용하는 반면 벡터 정의는 170바이트만 사용합니다. 따라서 플래시 사용량을 78% 절약할 수 있습니다.

이렇게 스토리지를 절약하면 성능이 떨어진다는 단점이 있습니다. 글리프를 그려야 하는 경우 벡터 정의를 픽셀로 변환해야 합니다. 이는 글리프의 벡터 정의를 조정하고 변환한 다음 프레임 버퍼로 렌더링하는 방식으로 이루어집니다.

Verdana 글꼴의 "G"는 20개의 베지어 곡선과 6개의 직선 부분으로 구성되어 있습니다. 이들은 모두 윤곽선으로 변환되며 최종적으로 선택한 텍스트 색으로 지정됩니다. 텍스트를 다시 그릴 때마다 텍스트의 모든 문자에 대해 이 프로세스가 반복됩니다.

위 프로세스에서는 GPU2D(예: STM32U5G9)가 있는 마이크로컨트롤러를 사용하는 경우 하드웨어 가속이 이루어집니다(잘 작동하는 경우). 부동 소수점 연산 하드웨어가 없어 느린 STM32G0과 같은 마이크로컨트롤러에서는 하드웨어가 이러한 연산을 수행하기 힘들 수 있습니다.

이런 경우 비트맵 글꼴을 사용하면 렌더링 시간이 개선됩니다. 따라서 플래시 절약이 필요한 경우 벡터 글꼴을 사용하고 그렇지 않은 경우에는 비트맵 글꼴을 사용하는 것이 좋습니다.
텍스트가 움직이는 경우(스크롤, 이동, 페이드) 비트맵 글꼴을 사용하는 것이 좋습니다.

구성

벡터 글꼴을 사용하려면 Vector RenderingVector Fonts 같은 추가 프레임워크 기능이 필요합니다. 이 항목은 STM32CubeMX에서 활성화됩니다. 자세한 정보는 Generator 사용자 가이드를 참조하십시오.

타이포그래피는 TouchGFX Designer에서 구성됩니다. 여기서 프로젝트의 타이포그래피가 비트맵 글꼴 형식을 사용할지 벡터 형식을 사용할지를 선택할 수 있습니다. 기본은 비트맵 글꼴 형식입니다.

벡터 글꼴 사용

벡터 글꼴은 TouchGFX에서 비트맵 글꼴을 사용하는 것과 같은 방식으로 사용됩니다. 텍스트를 이름이 있는 리소스 또는 Single Use 텍스트로 생성할 수 있습니다. 예를 들어 TextArea와 같은 위젯에서 텍스트를 표시합니다. 벡터 글꼴과 비트맵 글꼴의 차이는 렌더링 코드에 숨겨져 있습니다.

타이포그래피

TouchGFX Designer에서 타이포그래피가 벡터 기반으로 구성되는 경우 벡터 글꼴이 생성됩니다. Designer 사용자 가이드를 참조하십시오.

여러 타이포그래피가 동일한 글꼴(예: Verdana)을 사용하는 경우 이러한 타이포그래피는 프로젝트의 벡터 정의를 공유하지만 벡터 정의를 다른 스케일링 계수로 사용해 다양한 크기의 글리프를 생성합니다.

이는 또한 이러한 타이포그래피의 타이포그래피 속성 Fallback CharacterEllipsis Character가 같아야 함을 의미합니다.

타이포그래피에서 사용하는 문자(와일드카드 문자 포함)는 결합되어 동일한 글꼴을 사용하는 프로젝트의 모든 타이포그래피에 사용할 수 있습니다.

아키텍처

벡터 글꼴의 렌더링은 새로운 구성 요소인 VectorFontRenderer를 기반으로 합니다. 이 구성 요소는 VectorRenderer 구성 요소를 사용하여 글리프를 그립니다.

벡터 글꼴을 사용하는 프로젝트에서는 이 두 가지 구성 요소를 반드시 사용할 수 있어야 합니다. 이러한 구성 요소가 활성화된 경우 STM32CubeMX가 자동으로 이를 수행합니다. STM32CubeMX를 사용하지 않는 경우 수동으로 수행해야 합니다.

다음은 STM32CubeMX에서 생성한 코드입니다. 관련된 줄은 강조 표시되어 있습니다.

static STM32TouchController tc;
static STM32DMA dma;
static TouchGFXDataReader dataReader;
static LCD16bppSerialFlash display(dataReader);
static VectorFontRendererImpl vectorFontRenderer;
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);

display.setVectorFontRenderer(&vectorFontRenderer);
...

(TouchGFXGeneratedHAL.cpp에서) VectorRenderer 구성 요소도 제공되어야 합니다.

namespace touchgfx
{
VectorRenderer* VectorRenderer::getInstance()
{
static CWRVectorRendererRGB565 renderer;

return &renderer;
}
} // 네임스페이스 touchgfx

GPU2D 가속기가 있는 플랫폼에서는 CWRVectorRendererRGB565 대신 CPU2DVectorRenderer를 사용해야 합니다. 이렇게 하면 하드웨어 가속이 활성화됩니다.

제한 사항

곡선 규칙

TouchGFX 애플리케이션에서 사용하는 벡터 글꼴 타이포그래피는 글리프를 정확하게 그리기 위해 특정한 규칙을 따라야 합니다. 특히 외곽선이 겹치는 글리프의 경우 벡터 글꼴을 그릴 때 TouchGFX에 의해 배포되는 곡선 규칙 때문에 올바로 렌더링되지 않는 경우가 가끔 있습니다. 커스텀 타이포그래피에서 겹치는 외곽선을 제거하기 위해 무료 FontForge 도구를 사용하는 것이 좋습니다.

FontForge 사용

FontForge 설치 폴더(대개 c:/Program Files (x86)/FontForgeBuilds)로 이동하여 .exe 실행:

FontForge 실행 뷰.

사용자 프로젝트의 assets/fonts/ 폴더(예: c:/TouchGFXProjects/MyApplication/TouchGFX/assets/fonts/)로 이동합니다. FontForge가 애플리케이션의 모든 TrueType 글꼴을 감지합니다. 이 예에서 Cairo-Bold.ttf TrueType 글꼴은 올바로 그려지지 않는 겹치는 윤곽선을 가지고 있습니다.

FontForge에서 열린 TrueType 글꼴 뷰.

OK를 클릭하면 타이포그래피에 포함된 모든 글리프의 글꼴 뷰가 열립니다.

FontForge 글꼴 뷰.

글리프에서 겹치는 윤곽선을 제거하려면 Ctrl + A를 사용하여 글꼴 뷰에서 모든 글리프를 선택합니다. 그런 다음 모든 글리프가 선택된 상태에서 Ctrl + u와Ctrl + Shift + O 단축키를 차례로 사용하여 선택한 글리프에서 겹치는 윤곽선을 제거합니다. 모든 글리프 위에 글리프가 변경되었음을 의미하는 파란색 표시가 나타납니다. 개별 글리프를 더블 클릭하면 해당 효과를 볼 수 있습니다. 다음은 $ 글리프에서 겹치는 윤곽선을 제거하기 전과 후의 예제입니다.

겹치는 윤곽선이 있는 $ 글리프(왼쪽)와 겹치는 윤곽선이 없는 $ 글리프(오른쪽).

글리프의 외곽선은 영향을 받지 않았지만 겹쳤던 윤곽선이 합쳐진 것을 확인할 수 있습니다. TouchGFX 애플리케이션에서 겹치지 않는 타이포그래피를 사용하기 위해 FontForge를 사용해 새로운 글꼴을 내보냈습니다. FontForge 글꼴 뷰에서 Ctrl + Shift + G 단축키를 사용하여 글꼴을 내보냅니다. 이렇게 하면 글꼴 생성 뷰가 열립니다. 오류가 발생했을 때 원본 글꼴을 덮어쓰는 것을 방지하기 위해 예를 들어 "-no-overlap"과 같은 접미사를 붙여 타이포그래피 이름을 바꾸는 것이 좋습니다. 출력 형식으로 TrueType을 선택합니다. 아래와 같이 설정해야 합니다.

FontForge에서 생성된 글꼴 설정.

Generate를 눌러 글꼴을 내보냅니다. 경고가 나오면 Yes를 누릅니다. 내보낸 타이포그래피가 사용자 프로젝트의 assets/fonts/ 폴더에서 원본 TrueTye 글꼴 옆에 나타납니다. 이 폴더에서 원본 글꼴을 제거하고 디스크의 다른 곳에 보관하면 TouchGFX Designer에서 이름이 동일한 여러 타이포그래피가 표시되는 것을 피할 수 있습니다. TouchGFX Designer를 다시 시작해 글꼴 선택기에 새 글꼴이 표시되도록 합니다. 글꼴을 수정하기 전에 TouchGFX Designer에서 코드를 생성했다면 코드를 다시 생성하기 전에 generated/fonts/ 폴더를 제거합니다.

스토리지

벡터 글꼴 데이터는 메모리 매핑 영역에 저장해야 합니다. 여기에는 내부 플래시, 메모리 매핑 모드의 외부 QSPI/OSPI 플래시, RAM 또는 이와 비슷한 기타 메모리가 포함됩니다.

플랫폼에서 메모리 매핑 이외의 형식으로 글꼴 데이터를 저장하는 경우 링커 스크립트를 변경해 모든 벡터 글꼴 데이터를 (예를 들어) 내부 플래시로 옮겨야 합니다. 다음은 ARM gcc를 사용하여 이를 수행하는 방법입니다.

  /* "플래시" ROM 형식 메모리로 상수 데이터 이동 */
.FontFlashSection :
{
. = ALIGN(4);
*/Vector_*.o(FontFlashSection) /* 벡터 글꼴 데이터 */
. = ALIGN(4);
} >FLASH

FontFlashSection :
{
*(FontFlashSection FontFlashSection.*)
*(.gnu.linkonce.r.*)
. = ALIGN(0x4);
} >SPI_FLASH

이는 글꼴 데이터를 */Vector_*.o/와 일치하는 파일에서 FLASH 영역으로, 그리고 다른 글꼴 데이터를 SPI_FLASH 영역으로 옮깁니다.

벡터 글꼴 데이터는 generated/fonts/src/Vector_Font_Verdana.cpp 또는 비슷한 파일에 생성됩니다.

태국어

태국어는 벡터 글꼴을 사용하여 정확하게 렌더링할 수 없는 문제가 있습니다. 이 문제를 해결하려면 태국어에서 비트맵을 사용하십시오.