본문 바로가기

프로젝트/아두이노 한글 폰트 Code 자동생성 프로그램

TFT LCD SD카드 한글 출력 Index 방법

Index파일을 사용하면 빠르게 폰트 data를 찾아 표시 할 수 있다.

Index방법은 2가지 방법이 있다.

아두이노는 UTF-8 3Byte 한글코드를 사용한다

한글코드는 0xE28A82 ~ 0xEFBFA6 범위에 널려있다.

 

한곳에 모여 있어면  한글코드로 바로 폰트파일에서 폰트를 찾으면 되다.

(한글코드 - 시작 한글코드) * 폰트크기  :  폰트파일에서 폰트위치

 

그래서 중간에  Index파일을 사용하여 해결했다.

Index파일을 사용하면 빠르게 폰트 data를 찾아 표시 할 수 있다.

Index방법은 2가지 방법이 있다.

  Index방법 장점 단점 비고
인덱스 방법 1 빈코드를 포함한 Index 속도가 빠름 Index파일의 크기가 큼 혹시 방법 2로 속도가
안나오면 대신 사용
인덱스 방법 2 일반적인 Index ndex파일이 크기가
작음
글자에 따라 속도차가 있음  일반적으로 사용 권장

 

빈코드를 포함한 Index(방법1)
한글코드   Index파일 포인트 Index 파일 data   Font 파일 포인터 Font data
0   0 0   0 폰트0
빈코드   4 -1   32 폰트2
2 X 4 8 32   48 폰트3
3   12 48   64 폰트4
4   16 64   96 폰트6
빈코드   20 -1   128 폰트8
6   24 98      
빈코드   28 -1      
8   32 128      

 

일반 적인  Index (방법2)
한글코드   Index파일 포인트 한글코드 Index 파일 data   Font 파일 포인터 Font data
0   한글코드0 0   0 폰트0
빈코드   8 한글코드2 32   32 폰트2
2 한글코드검색 16 한글코드3 48   48 폰트3
3   24 한글코드4 64   64 폰트4
4   32 한글코드6 96   96 폰트6
빈코드   40 한글코드8 128   128 폰트8
6              
빈코드              
8              

방법2 한글코드 검색을 하는 coding이 필요 합니다 

처음부터 끝까지 비교 하는 방법은 간단하지만 시간이 많이 걸려 Index 하나 마나입니다. 

그래서 앞선 글에서 소개한 메뚜기 검색을 해야 힙니다.

  3056 코드 검색 예시
  now low high
0 5873 0 11746
1 2936 0 5873
2 4405 2936 5873
3 3670 2936 4405
4 3303 2936 3670
5 3119 2936 3303
6 3027 2936 3119
7 3073 3027 3119
8 3050 3027 3073
9 3061 3050 3073
10 3055 3050 3061
11 3058 3055 3061
  3056코드발견 3055 3058

 

단순하게 처음부터 검색하면  1번에서 11747번이 필요하다. 즉 평균 5,871번 검색이 필요합니다.

메뚜기 검색을 사용하면 대략 20번 안쪽으로 검색하면 됩니다.

그만큼 효율이 엄청 높아요. 

하지만 검색이 필요 없는 (방법1)보다는 조금 느림.


다음은 한글출력 Class의 메뚜기 검색 메소드입니다.

 

void getFont( long code )      // 한글코드를  인수로 받음   

{

       long low=0, high = 11746;   //  한글폰트(일부 특수문자 포함) 의 범위
       long now = 5873;                //   범위 중간값으로 검색시작 위치 설정 
       long hCode,hIdx;                //   Index파일에서 불러올 한글코드와 폰트파일 폰트 위치 저장변수
                                                  //   각각 4byte 필요함(long)  .. 아두이노 int는 2Byte임 
       long temp=-1;                  
       while(true)
       {
           _Index_File_.seek(now*8);           //  인덱스 레코드는 4+4로 8Byte임
           _Index_File_.read(&hCode,4);     // 한글코드 읽기
          if( hCode == code )    //  일치하는 한글코드 발결 하면
          {
            _Index_File_.seek(now*8+4);    // 레코드의 두번째 long타입 정수로 위치 이동  
            _Index_File_.read(&hIdx,4);      //  폰트파일 위치 읽기 
            _Font_File_.seek(hIdx);            //   폰트 파일에서 해당 폰트 위치로 이동
            _Font_File_.read(_HANGUL_FONT ,32); // 폰트 32Byte 읽기
            return;
          }
          else if( hCode > code ) high = now;    //  읽은코드 >  검색코드 이면   high를 현재 검색지점으로 설정
          else  low = now;                                  //  읽은 코드 <  검색코드이면   low 를 현재 검색지점으로 설정
          now=(low+high)/2;                              //   검색지점을 high와 low의 중간지점으로 재설정
          if( now==temp) return;                        //    새로운 검색지점이  전의 검색지점이 동일하면 No Found임
          else temp=now;                                  //    다음 검색을 위하여 검색지점 보관 
       }
    }