2016-09-20 8 views
0

현재 이모티콘을 지원하는 DrawTextEx() 함수를 직접 작성하고 있습니다. 이 함수를 사용하면 이모티콘이 텍스트에서 발견 될 때마다 콜백이 호출되어 발신자가 이미지로 이모티콘이 포함 된 텍스트 세그먼트를 바꿀 수 있습니다. 예를 들어 텍스트에있는 유니 코드 문자 0x3DD8 0x00DE는 텍스트가 그려지는 동안 웃는 얼굴 이미지로 바뀝니다. 사실이 함수는 잘 작동합니다."HTML 엔터티"이모티콘 코드를 UTF16으로 변환 (C++)

이제 발신자 측에서 이미지 라이브러리를 구현하고 싶습니다. 콜백 함수에서 0x3DD8 0x00DE와 같은 텍스트 세그먼트를받습니다. 제 생각은이 코드를 모든 유니 코드 조합을 포함하는지도에서 키로 사용하는 것입니다. 모든 코드 조합은 그릴 이미지가 포함 된 구조와 연결되어 있습니다. http://emojione.com/developers/ 웹 사이트에서 좋은 패키지를 발견했습니다. 이 사이트에서 사용할 수있는 모든 패키지에는 16 진수 코드 인 여러 파일 이름이 들어 있습니다. 따라서 패키지에 포함 된 파일을 반복하고 자동으로 맵을 만들 수 있습니다.

그러나이 코드는 다른 표준의 일부이며 사실 웹 개발에 사용 된 "HTML 엔터티"라는 항목 집합이라는 사실을 발견했습니다. 이는 http://graphemica.com/%F0%9F%98%80 웹 사이트에서 볼 수 있습니다. 따라서 이러한 파일을 사용할 수 있으려면 이름에 포함 된 HTML 엔터티 값을 UTF16 코드로 변환하는 솔루션이 필요합니다. 예를 들어 위에서 언급 한 웃는 얼굴의 경우 0x1f600 HTML 엔터티 코드를 0x3DD8 0x00DE UTF16 코드로 변환해야합니다.

무차별 접근 방식은 코드를 하나씩 코드에 추가하여 이러한 코드를 변환하는지도를 작성하는 것일 수 있습니다. 그러나 Unicode 표준에는 가장 낙관적 인 시나리오에서 이모티콘에 대한 1800 가지 이상의 조합이 포함되어 있으므로 필자는 알려진 API 또는 함수와 같은 기존 솔루션이 있음을 알고 싶습니다. 아니면 그렇게 할 수있는 알려진 트릭이 있습니까? 예를 들어

감사

답변

1

- (예 : "문자 + ('A' 'A')"와 같은 낮은 대문자 문자로 변환), 유니 코드는 0x3DD8 0x00DE가 대체됩니다 텍스트에서 발견가 문자 웃는 얼굴 화상

의해 문자 U + 1F600기만 얼굴 은 UTF-16 코드 유닛 시퀀스 0xD83D, 0xDE00 의해 표현된다.

(Graphemica 각 코드 단위의 바이트의 순서를 교환 슈퍼 오해의 소지가, 그 무시한다.)

나는이 코드가 다른 표준의 일부이며,라는 항목 집합이 사실에 발견 웹 개발에 사용 된 "HTML 엔터티"

HTML은 아무 관계가 없습니다. 그것들은 일반 Unicode 문자입니다. Basic Multilingual Plane 외부의 U + FFFF 위의 문자 들로서, UTF-16 코드 단위를 나타내는 데는 두 개 이상의 UTF-16 코드 단위가 필요합니다.

😀과 같은 HTML 숫자 문자 참조는 종종 코드 포인트 번호로 문자를 참조하는 방법이지만 HTML (또는 XML) 문서에서만 이스케이프 문자열이 효과적이며 그 중 하나에 없습니다.

그래서 :

나는 0x3DD8 0x00DE UTF16 코드에 0x1f600 HTML 엔티티 코드를 변환해야합니다.

더 같은 소리 :

내가 U + 1F600 씩 웃는 얼굴의 표현을 변환해야합니다 : 코드 포인트 번호 0x1F600에서 UTF-16 코드 단위 순서 0xD83D에,

0xDE00을

#이 될 것 C에서 어떤 :

string face = Char.ConvertFromUtf32(0x1F619); // "" aka "\uD83D\uDE00" 

또는 다른 방향으로

:

int codepoint = Char.ConvertToUtf32("\uD83D\uDE00", 0); // 0x1F619 

(여기서 'UTF-32'는 잘못 선택되었습니다. 우리는 정수 코드 포인트 수에 대해서 이야기하고 있습니다. 문자 당 4 바이트 시퀀스가 ​​아닙니다.)

또는이를 수행하는 알려진 트릭이 있습니까? (대문자를 낮은 값으로 변환하는 예 : "character + ('a'- 'A'))

C++에서 일이 더 성가시다. 코드 포인트와 UTF-16 코드 단위를 직접 변환하는 것은 없습니다 (생각할 수 있습니다). 다양한 인코딩 함수/라이브러리를 사용하여 UTF-32로 인코딩 된 바이트 시퀀스와 UTF-16 코드 단위 사이를 변환 할 수는 있지만 conversion logic을 직접 쓰는 것보다 더 많은 faff가 될 수 있습니다. 예는 단일 문자의 가장 기본적인 형태 :

std::wstring fromCodePoint(int codePoint) { 
    if (codePoint < 0x10000) { 
     return std::wstring(1, (wchar_t)codePoint); 
    } 
    wchar_t codeUnits[2] = { 
     0xD800 + ((codePoint - 0x10000) >> 10), 
     0xDC00 + ((codePoint - 0x10000) & 0x3FF) 
    }; 
    return std::wstring(codeUnits, 2); 
} 

이것은 wchar_t 형이라하고는 UTF-16 코드 단위, C#의 string 유형이 동일 기반으로한다. Windows에서는 이것이 사실 일 수 있습니다. 다른 곳에서는 그렇지 않을 수도 있지만 wchar_t이 코드 포인트를 기반으로하는 플랫폼에서는 추가 처리가없는 문자로 각 코드 포인트를 문자열에서 가져올 수 있습니다.

은 (최적화 및 오류 처리는 독자들에게 숙제로 남긴다.) 나는 RAD 스튜디오 컴파일러를 사용하고, 다행히도이 bobince에 의해 언급 또한 ConvertFromUtf32 및 ConvertToUtf32 기능에 대한 구현을 제공

0

. 나는 그것들을 시험했고, 나는 그들이 필요로하는 것을 정확하게했다.

엠바 카데로 제품을 사용하지 않는 제품의 경우, bobince에서 제공 한 fromCodePoint() 구현도 잘 작동합니다. 자세한 내용은 여기 RAD Studio에서 구현하고, 올바른 방향으로 절 지적하고이 문제를 해결하기 위해 나를 도와 그의 반응에 대한 bobince하는 C++

std::wstring ConvertFromUtf32(unsigned c) 
{ 
    const unsigned unicodeLastChar = 1114111; 
    const wchar_t minHighSurrogate = 0xD800; 
    const wchar_t minLowSurrogate = 0xDC00; 
    const wchar_t maxLowSurrogate = 0xDFFF; 

    // is UTF32 value out of bounds? 
    if (c > unicodeLastChar || (c >= minHighSurrogate && c <= maxLowSurrogate)) 
     throw "Argument out of range - invalid UTF32 value"; 

    std::wstring result; 

    // is UTF32 value a 16 bit value that can fit inside a wchar_t? 
    if (c < 0x10000) 
     result = wchar_t(c); 
    else 
    { 
     // do divide in 2 chars 
     c -= 0x10000; 

     // convert code point value to UTF16 string 
     result = wchar_t((c/0x400) + minHighSurrogate); 
     result += wchar_t((c % 0x400) + minLowSurrogate); 
    } 

    return result; 
} 

감사로 번역으로 또한 ConvertFromUtf32() 함수도있다.

감사합니다.