소형 LCD에 글자와 그림을 찍어야 할 상황이 생겼다.

사용하게 된 모델은 ILI9341. 2.2인치 TFT LCD로, SPI 통신으로 동작하는 모델[각주:1]이다.

 

MISO, MOSI를 아시나요…

 

뒤져보니 6x8 영문 폰트도 있고, 8x16 ASCII 폰트, 16x16 한글 폰트 등이 있었다.

이 폰트 파일들은 모두 한 픽셀을 한 비트(!!!)에 저장해서 크기를 극단적으로 줄인 코드들이다.

6x8 폰트는 너무 작아서[각주:2] 2~3배로 확대해야 볼만 하고, 16x16은 그나마 볼 수는 있는 크기이다.

일단 둘 다 적용.

 

3배로 확대한 6x8 영문 폰트와 2배로 확대한 32x32 한글 폰트

 

막상 적용하고 보니, 슬슬 글자 모양에 불만(?)이 생기기 시작한다.

나쁜 폰트는 아닌데, 워낙 오래된 느낌이 많이 나는 폰트이다.

또, 영문 폰트 아래에 1~2 픽셀의 공간이 있는데, 이것 때문에 글자가 좀 떠있는 느낌도 난다.

 

그래서 일단 해당 폰트들을 이미지로 추출하는 프로그램을 만들어봤다.

프로그램을 만드는 김에 각 글자 사이엔 경계선을 추가하기로 했고.

 

일단 영문 폰트.

 

0x00~0x1F 도 글자가 있음

 

다음은 한글 폰트.

 

실로 오랜만에 보는 조합형 한글 폰트

 

요즘은 모든 폰트가 완성형으로 한 글자씩 전문 디자이너 분들께서 만드시지만, 예전엔 그런 거 없었다.

당시에 조합형 한글을 잘 그려내기 위한 연구들이 있었는데, 대략의 결론이 초성은 8벌, 중성은 4벌, 종성은 4벌의 글자모양을 만들면 이걸 조합해서 모든 글자를 보기 좋게 출력할 수 있다는 것이었다.

이 생각이 반영된 것이 위에 보이는 표다.

360개의 폰트만 있으면 유니코드 표의 11,172 자를 모두 조합[각주:3]해서 그려낼 수 있는 것이다.

 

예제 삼아서 완성형 한글 2,350자(KS2350)를 조합해주는 기능도 이 프로그램에 추가했다.

 

완성형 한글 2,350자의 위엄. 똠방각하, 펲시콜라 등은 출력할 수 없음

 

여기까지 만들고 보니 이제 쓸데 없는 욕심이 들기 시작한다.

8x16, 16x16 글자 모양만 있으면 역순으로 돌려서 폰트 코드를 만들 수 있을텐데[…]

 

 

뒤져보니 일단 영문 8x16 폰트는 아타리 사의 것이 잘 나온 것 같다.

 

편의상 0x80 이후 절삭

 

영문 폰트는 일단 여기서 멈추고, 한글 폰트를 뒤져봤다.

 

지하철에도 사용된다는 둥근모꼴의 위엄

 

당연히 16x16 폰트에 대한 많은 시도들이 있었고, 이 중 김중태 님께서 만드신 둥근모꼴의 완성도가 높은 것 같았다.

이 폰트는 소스 코드[각주:4]를 구할 수는 없었지만, 애초에 목표가 글자에서 폰트 코드를 추출하는 것이라 문제는 없었다.

 

그런데, 사실 둥근모꼴 원본에 포함된 영숫자는 예쁘지 않았고, 해당 링크에도 이미 Fixedsys로 교체되어 있었다.

그래서, 이미 능력자 분께서 Neo둥근모 프로젝트를 통해 둥근모꼴도 살짝 다듬고, 적절한 영문 폰트도 적용해놓으셨다.

 

Neo둥근모에 사용된 영문 폰트를 추출하면 아래와 같다.

 

0x1F 이하는 아타리 것

 

한글은 필요한 자소가 포함된 글자를 모두 메모장에 입력한 뒤에 해당 자소만 발췌[각주:5]했다.

 

역시 paint.net은 폰트 작업의 최고의 친구죠

 

이 자소들을 적절히 2,350번 조합하면 역시 아래와 같은 KS2350 글자들을 볼 수 있다.

전체적으로 모양이 잘 나와서 위의 테이블을 사용하면 충분하다는 결론.

 

물론, 이 표는 KS2350이지만, 적절하게 인자만 전달하면 유니코드 11,172자를 모두 출력 가능함

 

마지막으로 위의 영문 폰트와 한글 자소 폰트를 읽어 비트 단위로 인코딩해서 C 소스로 만들어주는 프로그램을 만드는 것으로 기나긴 턴을 종료했다.

 

아래는 결과물의 극히 일부.

 

//converted with LCDFontTool by BLUEnLIVE 
const unsigned char E_font[128][16] = { 
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, // 0x00 
{0xc0,0x60,0x30,0x18,0x18,0x30,0x60,0xc0, 0x01,0x01,0x1f,0x10,0x10,0x1f,0x01,0x01,}, // 0x01 
{0x80,0x80,0xf8,0x08,0x08,0xf8,0x80,0x80, 0x03,0x06,0x0c,0x18,0x18,0x0c,0x06,0x03,}, // 0x02 
{0xe0,0x20,0x3c,0x0c,0x18,0x30,0xe0,0xc0, 0x01,0x01,0x0f,0x0c,0x06,0x03,0x01,0x00,}, // 0x03 

 

//converted with LCDFontTool by BLUEnLIVE 
const uint8_t K_font[360][32] = { 
{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, 
{0x00,0x08,0x08,0x08,0x08,0xf8,0xf8,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
 0x00,0x00,0x20,0x20,0x30,0x1f,0x0f,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, 
{0x00,0x08,0x08,0xf8,0xf8,0x08,0xf8,0xf8, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 
 0x00,0x20,0x30,0x1f,0x0f,0x20,0x3f,0x1f, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,}, 
{0x00,0xf8,0xf8,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 

 

 

  1. 같은 모델명에 병렬 인터페이스를 사용하는 모델도 있음 [본문으로]
  2. 애초에 화면이 2.2인치임 [본문으로]
  3. 세종대왕 님 고맙습니다. 이 모두는 대왕님의 덕분입니다. [본문으로]
  4. 글꼴 이미지 파일은 있지만, 이를 C 코드 등으로 추출한 소스가 없어서 큰 의미가 없음 [본문으로]
  5. 전 작업 과정 중에서 유일하게 여기서만 수작업을 함 [본문으로]

+ Recent posts