개발/아두이노-Arduino

[SPI/TFT...] 디스플레이에 텍스트, 문자가 출력되는 원리

어중E 2022. 9. 20. 14:41

[SPI/TFT...] 디스플레이에 텍스트, 문자가 출력되는 원리

SPI를 사용하는 디스플레이는 여럿이 있습니다. ST7789 시리즈나 SSD1306가 있습니다. 이 디스플레이에서 텍스트(영어, 한글, 라틴, 유니코드 등)를 출력하는 원리는 동일합니다. 원리는 생각보다 간단합니다. 도트 하나하나 찍어서 연속적으로 출력합니다. 이는 문자뿐만 아니라 비트맵도 해당됩니다.

 

예를 들어 폰트의 width, height가 각각 24, 24로 설정된 폰트가 있다면,  한글 '가'는 다음과 같이 표현됩니다.

 

가로세로 모두 24픽셀로 특정 픽셀만 표시를 하여 '가'를 표시합니다. 그리고 한글 '가'를 표현하기 위해서는 아마 다음과 같은 코드들이 필요할겁니다. (아래 코드는 원리 이해의 예시로만 참고해주세요)

// 가로 24, 세로 24 픽셀을 1차원 배열로 저장
uint8_t text[] = {
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,0,1, 1,0,0,0,
    0,0,0,1,1, 1,1,1,1,1, 1,1,1,1,1, 1,1,1,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,1,1,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,1,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 1,1,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,1,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,1,1, 1,0,0,0,1, 1,1,1,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,1,1,1, 0,0,0,0,1, 1,1,1,0,
    0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,1, 1,1,1,0,
    0,0,0,0,0, 0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,1, 1,1,1,0,
    0,0,0,0,0, 0,0,0,0,0, 1,1,1,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,1, 1,1,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,1,1, 1,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,1,1,1, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,1,1,1, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,1,1,1,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 1,1,1,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,1, 1,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,
    0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0,0, 0,0,0,0
}

for(int i = 0; i<24; i++)
{
	for(int j=0; j<24; j++)
	{
		drawPixel(x, y, text[i*23 + j]); //좌표 x,y에 text 배열을 순서대로 표시
	}
}

 

 

※drawPixel은 임시 함수이며, 내부에는 SPI 통신과 관련된 코드들이 있다고 가정합니다. 또한 비트를 16진수로 표시하는 방법을 많이 사용하지만 이해를 위해 위와 같이 표시하였습니다.

 

이 코드들은 아래와 같은 방향으로 되었습니다. 위의 코드에서 x,y 의 좌표는 디스플레이에서의 좌표이며, 이 좌표로부터 아래 0,0 부분에 해당되는 픽셀들이 표시되거나 표시되지 않게 됩니다.

 

 

위의 방향은 기본적인 방향이지만, 가끔 변태적인(?) 방향으로 폰트를 표시하거나 설정해놓은 오픈소스들이 있습니다. 

이런 경우에는 해당 폰트 파일을 가져와 사용하면 글씨가 깨진 듯이 나오게 되는데, 이때에는 출력 방향을 변경해서 설정해주면 폰트를 잘 읽어와 디스플레이에 뿌려줄 수 있습니다. 하지만 이보다 더 변태적일 수도 있지만, 생각하진 않겠습니다. 제가 만나본 오픈소스의 코드의 폰트 형태는 마지막과 동일했습니다.

 

보통 24*24 픽셀의 폰트의 형태로 유니코드 전부를 비트화 시킨다면 보통 4Mb 정도 차지합니다. 영어만 포함시키면 용량이 얼마 되지 않지만, 한글은 양이 엄청 많기 때문에 영어만 포함되었을 때와 비교하면 엄청 늘어납니다.

 

그렇다면 어떻게 '가'라는 것을 가리킬(?) 수 있는지 보면 유니코드와 UFT-8을 확인해야 합니다. UFT-8은 한글을 3바이트에 표시하는 방법입니다. 이 방법으로 유니코드를 알아내고 해당 유니코드로 '가'를 표시하는 비트 배열을 가리켜서 각 픽셀을 찍어내 문자를 표시할 수 있게 합니다. 유니코드와 UTF-8은 추후 다른 글로 자세히 설명드리겠습니다.