최근 Fedora Linux 설치 시 OS UI 및 브라우저에 이모티콘이 표시되는 문제가 발생했습니다. 이 문제로 인해 글꼴 구성 프로젝트를 조금 조사하게 되었지만 구성과 글꼴을 테스트하려면 모든 유니코드 버전에서 이모티콘을 생성해야 했고, 이로 인해 결국 모든 이모티콘과 일부를 인쇄하는 Golang "스크립트"를 작성하게 되었습니다. 내부 정보에 대한 정보입니다.
이번 여행을 통해 저는 이모티콘의 내부, 이진 표현, 그리고 이모티콘과 관련하여 유니코드 표준에서 내린 이상하고 귀여운 결정에 대해 자세히 알아봤습니다.
하지만 먼저 잠시 뒤로 돌아가서 몇 가지 용어집을 요약해 보겠습니다.
우리는 인코딩을 언어 문자와 이 문자의 이진 표현 사이의 "매핑" 또는 "번역"으로 설명할 수 있습니다. 예를 들어, 기존 ASCII 인코딩은 문자 a를 0x61 16진수(0b01100001 바이너리)로 매핑합니다. 인코딩의 예로는 Microsoft(Windows 125x) 또는 ISO(ISO/IEC 8859) 8비트 코드 페이지가 있습니다.
이러한 고정 8비트 코드 페이지에서 사용되는 정보의 최소 "양"은 8비트(1바이트)입니다. 즉, 256개의 서로 다른 문자/문자를 포함할 수 있습니다. 다양한 언어를 지원하기 위해 256개의 바이너리 코드를 재사용하여 다양한 코드 페이지가 생성되었습니다. 따라서 [0xD0, 0xE5, 0xF2] 3바이트가 기록된 텍스트 파일은 그리스어 ISO 8859-7을 사용하여 "Πες"로 읽거나 서부 ISO 8859-7을 사용하여 "Ðåò"로 읽습니다(동일 바이트, 다르게 해석됨). 코드 페이지 기준).
어떤 시점에서는 기술이 발전함에 따라 다양한 코드 페이지가 확장되지 않았습니다. 그래서 우리는 모든 언어(및 그 이상)에 적합하고 시스템 전반에 걸쳐 통합될 수 있는 것이 필요했습니다.
[ 빨리감기하여 많은 역사와 표준을 남겨두고 현재까지 ]
유니코드 표준은 디지털화할 수 있는 전 세계 모든 쓰기 시스템을 지원하도록 설계되었습니다. 따라서 위의 예를 사용하면 유니코드 표준에서 그리스 문자 "Π"는 코드 0x03A0을 갖는 반면 라틴 대문자 eth "Ð"는 코드 0x00D0을 가지며 더 이상 충돌하지 않습니다. 유니코드 표준에는 버전이 있으며, 작성 당시 최신 버전은 16.0(스펙)입니다.
근데 잠깐만요, 이 "코드 포인트"가 뭐죠?
유니코드 표준에서는 모든 "문자", 제어 문자, 이모티콘 및 일반적으로 정의된 모든 항목에 "코드 포인트"라는 고유한 이진 값이 있습니다. 표준은 모든 코드 포인트를 정의하며, 각 코드 포인트에는 순수 코드/바이너리 정보가 포함됩니다. 각 코드 포인트의 16진수 형식은 일반적으로 U 접두사로 작성됩니다. 예를 들어 그리스 소문자 오메가(Ω) 코드 포인트는 U 03C9입니다.
그럼 실제로 누가 해당 코드 포인트를 인코딩합니까?
코드 포인트를 바이트로 인코딩하는 첫 번째 부분은 인코딩 양식입니다. 표준에 따르면:
인코딩 형식은 유니코드 문자의 각 정수(코드 포인트)가 하나 이상의 코드 단위 시퀀스로 표현되는 방법을 지정합니다.
인코딩 양식에서는 "코드 단위"라는 용어를 사용하여 특정 인코딩 내에서 유니코드 코드 포인트를 나타내는 데 사용되는 데이터의 가장 작은 단위를 나타냅니다.
유니코드 표준은 세 가지 인코딩 형식을 정의합니다.
이는 사용된 인코딩 형식에 따라 단일 코드 포인트 또는 일련의 코드 포인트가 다르게 인코딩될 수 있음을 의미합니다.
유니코드에서 실제 바이너리 직렬화를 처리하는 레이어를 인코딩 체계라고 하며 모든 하위 수준 세부 사항(예: 엔디안)을 처리합니다. 유니코드 사양의 표 2-4:
|Encoding Scheme| Endian Order | BOM Allowed? | | ------------- | ----------------------------| ------------ | | UTF-8 | N/A | yes | | UTF-16 | Big-endian or little-endian | yes | | UTF-16BE | Big-endian | no | | UTF-16LE | Little-endian | no | | UTF-32 | Big-endian or little-endian | yes | | UTF-32BE | Big-endian | no | | UTF-32LE | Little-endian | no |
참고: 거의 모든 최신 프로그래밍 언어, OS 및 파일 시스템은 유니코드(인코딩 체계 중 하나 포함)를 기본 인코딩으로 사용합니다. Java와 .NET은 UTF-16을 사용하는 반면 Golang은 UTF-8을 내부 문자열 인코딩으로 사용합니다. 즉, 메모리에 문자열을 생성하면 언급된 인코딩 형식을 사용하여 유니코드로 인코딩됩니다.
유니코드 표준은 이모티콘에 대한 코드 포인트도 정의하며(버전 번호와 약간의 혼동 후) 이모티콘 "표준" 버전은 유니코드 표준과 병행하여 진행됩니다. 작성 당시 Emoji는 "16.0"이고 Unicode Standard는 "16.0"입니다.
예:
⛄ 눈 없는 눈사람 (U 26C4)
? 웃는 눈과 세 개의 하트가 있는 웃는 얼굴 (U 1F970)
유니코드는 변형 및 피부색과 같이 이모티콘의 기본 코드 포인트를 따를 수 있는 수정자를 정의합니다(변형 부분은 탐색하지 않습니다).
EMOJI MODIFIER FITZPATRICK TYPE-X(x는 1~6)라고 하는 6개의 피부색 수정자(Fitzpatrick 척도에 따름)가 있으며 이는 모든 인간 이모티콘에 영향을 미칩니다.
밝은 피부색 (피츠패트릭 Type-1-2) (U 1F3FB)
약간 밝은 피부색(피츠패트릭 타입-3) (U 1F3FC)
중간 피부색(피츠패트릭 Type-4) (U 1F3FD)
중간-어두운 피부색(Fitzpatrick Type-5) (U 1F3FE)
어두운 피부색(피츠패트릭 Type-6) (U 1F3FF)
예를 들어 모든 인간 이모티콘과 마찬가지로 아기 이모티콘도 ? (U 1F476) 뒤에 스킨 수정자가 없으면 중간 노란색으로 나타납니다. 대조적으로, 피부색 수정자가 뒤에 오면 그에 따라 변경됩니다.
? U 1F476
?? U 1F476 U 1F3FF
?? U 1F476 U 1F3FE
?? U 1F476 U 1F3FD
?? U 1F476 U 1F3FC
?? U 1F476 U 1F3FB
이모지/유니코드 표준의 가장 이상하지만 귀엽다 결정은 일부 이모지가 독립형 코드 포인트 없이 Zero Width Joiner를 사용하여 다른 이모지를 결합하여 정의되었다는 것입니다.
예를 들어 다음을 결합하면:
백기 ?️ (U 1F3F3 U FE0F)
제로폭 조이너(U 200D)
무지개 ? (U 1F308)
무지개 깃발로 나타납니다 ?️? (U 1F3F3 U FE0F U 200D U 1F308)
또는, ?? ? => ???
아니면, ?? ❤️ ? ?? => ??❤️???
이모지를 함께 쥐어짜면 쯧쯧, 새로운 이모티콘이 나타나는 것과 같습니다. 정말 귀엽죠?
저는 모든 이모티콘이 포함된 마크다운 테이블을 만들고 싶었고, 유니코드 이모티콘 시퀀스 테이블이 이에 대한 정보 소스입니다.
https://unicode.org/Public/emoji/16.0/emoji-sequences.txt
https://unicode.org/Public/emoji/16.0/emoji-zwj-sequences.txt
그래서 저는 해당 시퀀스 파일을 가져와서 구문 분석하고, 시퀀스 파일에 범위가 설명될 때 각 이모티콘을 생성하고, 각 항목에 대한 일부 내부 정보가 포함된 마크다운 테이블을 인쇄하는 Golang 파서(여기)를 만들었습니다(예: 부분 결합된 경우 또는 베이스 피부톤 등).
여기에서 마크다운 테이블을 찾을 수 있습니다.
이 테이블의 마지막 열은
str := "⌚" len([]rune(str)) // 1 len([]byte(str)) // 3
우리가 논의한 것처럼 Golang 내부 문자열 인코딩은 UTF-8입니다. 이는 예를 들어 시계 이모티콘 ⌚의 경우 바이트 길이가 3이라는 것을 의미합니다(UTF-8은 이 코드 포인트를 "쓰기" 위해 3바이트를 생성하기 때문입니다). 코드 포인트 길이는 1입니다.
Golang 룬 == 유니코드 코드 포인트
그러나 결합된 이모티콘의 경우 - 하나로 "표시되더라도" 코드 포인트(룬)와 바이트가 더 많습니다.
str := "??❤️???" len([]rune(str)) // 10 len([]byte(str)) // 35
그 이유는 다음과 같습니다.
??❤️??? : ?? ZWJ ❤️ ZWJ ? ZWJ ?? ?? : 1F469 1F3FC // ? skin tone modifier [2 code points] ZWJ : 200D // [1 code points] * 3 ❤️ : 2764 FE0F // ❤ VS16 for emoji-style [2 code points] ? : 1F48B // [1 code point] ?? : 1F468 1F3FE // ? skin tone modifier [2 code points]
?
이모지를 보는 방식은 시스템 글꼴과 이 글꼴이 지원하는 이모지 버전에 따라 다르다는 점을 언급할 가치가 있습니다.
글꼴 렌더링의 정확한 내부와 결합된 글꼴을 올바르게 렌더링할 수 있는 방법을 모르겠습니다. 아마도 그것은 미래의 게시물이 될 것입니다.
그때까지 건배하세요 ?
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3