2009-03-19 1 views
1

현재 임베디드 디스플레이 용 글꼴 엔진을 설계하고 있습니다. 기본적인 문제는 다음과 같습니다.UTF-8 지원 및 관련 글꼴 테이블을 포함 된 프로젝트에 추가하려면 어떻게합니까?

동적으로 생성 된 텍스트 문자열을 가져 와서 UTF-8 테이블에서 해당 문자열의 값을 조회 한 다음 테이블을 사용하여 지원되는 모든 압축 비트 맵 배열을 가리켜 야합니다. 문자. 완료되면 비트 맵 배열의 데이터를 디스플레이로 이동시키는 비트 복사 루틴을 호출합니다.

(32K ROM, 8K RAM)으로 작업 할 수있는 시스템 자원이 매우 부족하기 때문에 전체 UTF-8 문자 세트를 지원하지는 않지만 나중에 현지화를 위해 필요한 글리프를 추가 할 수 있기를 바랍니다 목적. 모든 개발은 C 및 어셈블리에서 수행됩니다.

글리프 크기는 최대 16 비트 폭과 16 비트 높이입니다. 우리는 더 큰 고객의 일부가 아시아에 있기 때문에 아마도 Basic Multilingual Plane (3 바이트) 전체에 대한 지원을 필요로 할 것입니다. 그러나 특정 지역화에 전체 표를 포함시키지 않을 것입니다.

내 질문은 :
이 UTF-8 지원 및 관련 테이블을 추가하는 가장 좋은 방법은 무엇입니까?

답변

1

아래의 솔루션은 유니 코드 공간의 하위 16 비트가 충분하다고 가정합니다. 비트 맵 테이블이 위치 0x00 ~ 0x5E에서 U + 00A ~ U + 0000, 위치 0x5F ~ 0xBE에 U + 00A0에서 U + 00FF, 0xBF에서 0xFF에 U + 1200 ~ U + 1241이라면 다음과 같은 작업을 수행 할 수 있습니다. 아래의 코드 (테스트되지 않았고 심지어 컴파일 테스트되지 않음).

bitmapmap에는 일련의 값 쌍이 들어 있습니다. 첫 번째 쌍의 첫 번째 값은 인덱스 0의 비트 맵이 나타내는 유니 코드 코드 포인트입니다. 비트 맵 테이블에는 일련의 직접 인접한 유니 코드 코드 포인트가 포함된다고 가정합니다. 두 번째 값은이 시리즈의 지속 시간을 나타냅니다.

while 루프의 첫 번째 부분은 UTF-8 입력을 반복하고 ucs2char에서 유니 코드 코드 포인트를 작성합니다. 완전한 문자가 발견되면, 두 번째 부분은 bitmapmap에 언급 된 범위 중 하나에서 해당 문자를 검색합니다. 적절한 비트 맵 인덱스를 찾으면이를 인덱스에 추가합니다. 비트 맵이없는 문자는 자동으로 삭제됩니다.

이 함수는 찾은 비트 맵 인덱스의 수를 반환합니다.

이 작업을 수행하는 방법은 유닉스 -> 비트 맵 테이블의 관점에서 합리적으로 빠르고 합리적으로 유연해야합니다.

// Code below assumes C99, but is about three cut-and-pastes from C89 
// Assuming an unsigned short is 16-bit 

unsigned short bitmapmap[]={0x0020, 0x005E, 
          0x00A0, 0x0060, 
          0x1200, 0x0041, 
          0x0000}; 

int utf8_to_bitmap_indexes(unsigned char *utf8, unsigned short *indexes) 
{ 
    int bitmapsfound=0; 
    int utf8numchars; 
    unsigned char c; 
    unsigned short ucs2char; 
    while (*utf8) 
    { 
     c=*utf8; 
     if (c>=0xc0) 
     { 
      utf8numchars=0; 
      while (c&0x80) 
      { 
       utf8numchars++; 
       c<<=1; 
      } 
      c>>=utf8numchars; 
      ucs2char=0; 
     } 
     else if (utf8numchars && c<0x80) 
     { 
      // This is invalid UTF-8. Do our best. 
      utf8numchars=0; 
     } 

     if (utf8numchars) 
     { 
      c&=0x3f; 
      ucs2char<<=6; 
      ucs2char+=c; 
      utf8numchars--; 
      if (utf8numchars) 
       continue; // Our work here is done - no char yet 
     } 
     else 
      ucs2char=c; 

     // At this point, we have a complete UCS-2 char in ucs2char 

     unsigned short bmpsearch=0; 
     unsigned short bmpix=0; 
     while (bitmapmap[bmpsearch]) 
     { 
      if (ucs2char>=bitmapmap[bmpsearch] && ucs2char<=bitmapmap[bmpsearch]+bitmapmap[bmpsearch+1]) 
      { 
       *indexes++ = bmpix+(ucs2char-bitmapmap[bmpsearch]); 
       bitmapsfound++; 
       break; 
      } 

      bmpix+=bitmapmap[bmpsearch+1]; 
      bmpsearch+=2; 
     } 
    } 
    return bitmapsfound; 
} 

EDIT : 하위 16 비트 이상을 필요로한다고 언급했습니다. s/unsigned short/unsigned int /; s/ucs2char/codepoint /; 위의 코드에서 전체 유니 코드 공간을 수행 할 수 있습니다.

+0

훌륭한 답변, 도움 주셔서 감사합니다. –

0

문자의 크기를 지정하지 않았거나 문자 집합의 크기를 지정하지 않았으므로 크기 요구 사항을 예측하기가 어렵습니다.

문자의 크기에 따라 비트 맵을 직선 배열 형식으로 저장 하겠지만 요소를 압축하거나 풀지 않아도 상당히 효율적으로 저장할 수 있습니다.

예를 들어, 8x6 문자로 36 문자 알파벳을 사용하는 경우 배열에 216 바이트의 저장 공간이 필요합니다. (6 바이트/문자 * 36 - 각 바이트는 문자의 세로 슬라이스입니다.)

구문 분석의 경우 테이블에서 오프셋을 수행하기 만하면됩니다.
오래된 (char - 'A') 및 (char - '0') 트릭은 아주 잘합니다.

다른 질문은 비트 맵 배열을 저장할 위치입니다. ROM에는 분명한 대답이 있지만 다른 글리프를 지원해야하는 경우 다시 프로그래밍해야 할 수도 있습니다. 문제가되는 경우 지정하지 않아도됩니다.

글리프를 동적으로 프로그래밍해야하는 경우 선택 사항이 없지만 RAM에 저장해야합니다.

+0

의견을 보내 주셔서 감사 드리며, 문제의 설명을 업데이트하여 문자 크기를 포함하고 (모호하게) 문자 집합의 크기에 대한 질문에 대답하도록하겠습니다. –

관련 문제