Dernièrement, j'ai eu un problème avec mon installation Fedora Linux affichant des emojis dans l'interface utilisateur du système d'exploitation et dans les navigateurs. Ce problème m'a amené à enquêter un peu sur le projet de configuration des polices, mais pour tester mes configurations et mes polices, j'avais besoin de produire des emojis à partir de toutes les versions Unicode, ce qui m'a finalement amené à écrire un "script" Golang pour imprimer tous les emojis et certains informations sur leurs composants internes.
Tout au long de ce voyage, j'ai plongé en profondeur dans les composants internes des emojis, leurs représentations binaires et certaines des décisions étranges/mignonnes prises par la norme Unicode concernant les emojis.
Mais d'abord, prenons un peu de recul et résumons un glossaire.
On pourrait décrire l'encodage comme le « mappage » ou la « traduction » entre une lettre d'une langue et la représentation binaire de cette lettre. Par exemple, le codage ASCII traditionnel mappe la lettre a en 0x61 hex (0b01100001 binaire). Des exemples de codages sont les pages de codes Microsoft (Windows 125x) ou ISO (ISO/IEC 8859) à 8 bits.
Dans ces pages de codes fixes de 8 bits, la « quantité » minimale d'informations utilisée est de 8 bits (1 octet), ce qui signifie qu'elles peuvent contenir 256 lettres/caractères différents. Différentes pages de codes ont été créées en réutilisant les 256 codes binaires pour prendre en charge de nombreuses langues. Ainsi, avoir un fichier texte avec ces 3 octets écrits dessus [0xD0, 0xE5, 0xF2] se lit comme "Πες" en utilisant l'ISO grec 8859-7, ou "Ðåò" en utilisant l'ISO 8859-7 occidental (mêmes octets, interprétés différemment basé sur la page de codes).
À un moment donné, le fait d'avoir de nombreuses pages de codes différentes n'a pas bien évolué à mesure que la technologie progressait. Nous avions donc besoin de quelque chose qui puisse s'adapter à toutes les langues (et plus encore) et être unifié entre les systèmes.
[ avance rapide, laissant de côté beaucoup d'histoire et de normes, jusqu'au présent ]
La norme Unicode a été conçue pour prendre en charge tous les systèmes d'écriture du monde pouvant être numérisés. Ainsi, en reprenant l'exemple ci-dessus, dans les standards Unicode, la lettre grecque "Π" a le code 0x03A0 tandis que la lettre majuscule latine eth "Ð" a le code 0x00D0 et n'entrent plus en collision. Unicode Standard a des versions, et au moment de la rédaction, la dernière version est 16.0 (spéc.).
Mais attendez une minute, c'est quoi ce "point de code" ?
Dans la norme Unicode, chaque « lettre », caractère de contrôle, emoji et chaque élément défini en général a une valeur binaire unique appelée « point de code ». La norme définit tous les points de code, et chaque point de code contient des informations pures de code/binaire. Le format hexadécimal de chaque point de code est généralement écrit avec un préfixe U. Par exemple, le point de code de la lettre minuscule grecque Omega (ω) est U 03C9.
Alors, qui codons-nous réellement ces points de code ?
La première partie du codage des points de code en octets est le codage des formulaires. Selon la norme :
Les formes de codagespécifient comment chaque entier (point de code) d'un caractère Unicode doit être exprimé sous la forme d'une séquence d'une ou plusieurs unités de code.
Les formulaires de codage utilisent le terme « unité de code » pour désigner la plus petite unité de données utilisée pour représenter un point de code Unicode dans un codage particulier.
La norme Unicode définit trois formes de codage différentes :
Cela signifie qu'un seul point de code ou une séquence de points de code peut être codé différemment selon la forme de codage utilisée.
La couche qui s'occupe de la sérialisation binaire réelle dans Unicode est appelée Encoding Schemes et s'occupe de tous les détails de bas niveau (tels que l'endianité). Tableau 2-4 de la spécification Unicode :
|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 |
Remarque : presque tous les langages de programmation, systèmes d'exploitation et systèmes de fichiers modernes utilisent Unicode (avec l'un de ses schémas de codage) comme codage natif. Java et .NET utilisent UTF-16, tandis que Golang utilise UTF-8 comme codage de chaîne interne (cela signifie que lorsque nous créons une chaîne en mémoire, elle est codée en Unicode avec la forme de codage mentionnée)
Le standard Unicode définit également des points de code pour les emojis (beaucoup d'entre eux), et (après quelques confusions avec le numéro de version), la version du "standard" Emoji progresse en parallèle avec le standard Unicode. Au moment de la rédaction, nous avons Emoji « 16.0 » et Unicode Standard « 16.0 ».
Exemples :
⛄ Bonhomme de neige sans neige (U 26C4)
? Visage souriant avec des yeux souriants et trois cœurs (U 1F970)
Unicode définit des modificateurs qui pourraient suivre le point de code de base d'un emoji, tels que la variation et le teint (nous n'explorerons pas la partie variation).
Nous avons six modificateurs de teint (suivant l'échelle de Fitzpatrick) appelés EMOJI MODIFIER FITZPATRICK TYPE-X (où x est compris entre 1 et 6), et ils affectent tous les emojis humains.
Peau claire (Fitzpatrick Type-1-2) (U 1F3FB)
Peau moyennement claire (Fitzpatrick Type-3) (U 1F3FC)
Peau moyennement teintée (Fitzpatrick Type-4) (U 1F3FD)
Peau moyennement foncée (Fitzpatrick Type-5) (U 1F3FE)
Peau foncée (Fitzpatrick Type-6) (U 1F3FF)
Donc, par exemple, comme tous les emojis humains, l'emoji bébé ? (U 1F476), lorsqu'il n'est pas suivi d'un modificateur de peau, apparaît dans une couleur jaune neutre. En revanche, lorsqu’un modificateur de couleur de peau le suit, il change en conséquence.
? U1F476
?? U 1F476 U 1F3FF
?? U 1F476 U 1F3FE
?? U 1F476 U 1F3FD
?? U 1F476 U 1F3FC
?? U 1F476 U 1F3FB
La décision la plus étrange mais mignonne de la norme Emoji/Unicode est que certains emojis ont été définis en joignant d'autres ensemble à l'aide du Zero width Joiner sans point de code autonome.
Donc, par exemple, lorsque nous combinons :
Drapeau blanc ?️ (U 1F3F3 U FE0F)
Menuisier à largeur nulle (U 200D)
Arc-en-ciel ? (U1F308)
Il apparaît comme Rainbow Flag ?️ ? (U 1F3F3 U FE0F U 200D U 1F308)
Ou, ?? ? => ???
Ou même, ?? ❤️ ? ?? => ??❤️???
C'est comme si on rassemblait des emojis, et puis, pouf ?, un nouvel emoji apparaît. Est-ce que c'est mignon ?
Je voulais créer un tableau Markdown avec tous les emojis, et les tableaux de séquences d'emojis Unicode sont la source de vérité pour cela.
https://unicode.org/Public/emoji/16.0/emoji-sequences.txt
https://unicode.org/Public/emoji/16.0/emoji-zwj-sequences.txt
J'ai donc créé un analyseur Golang (ici) qui récupère et analyse ces fichiers de séquence, génère chaque emoji lorsqu'une plage est décrite dans le fichier de séquence et imprime un tableau de démarques avec des informations internes pour chacun (comme le pièces au cas où elles seraient jointes, ou la base teinte de peau, etc.).
Vous pouvez trouver le tableau des démarques ici.
La dernière colonne de ce tableau est au format
str := "⌚" len([]rune(str)) // 1 len([]byte(str)) // 3
Comme nous en avons discuté, le codage de chaîne interne de Golang est UTF-8, ce qui signifie que, par exemple, pour l'emoji d'horloge ⌚ la longueur d'octet est de 3 (car l'UTF-8 produit 3 octets pour "écrire" ce point de code), et la longueur du point de code est de 1.
Rune Golang == Point de code Unicode
Mais dans le cas d'emoji joints -même s'ils "apparaissent" comme un seul- nous avons de nombreux points de code (runes) et encore plus d'octets.
str := "??❤️???" len([]rune(str)) // 10 len([]byte(str)) // 35
Et la raison est la suivante :
??❤️??? : ?? 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]
?
Il convient de mentionner que la façon dont nous voyons les emojis dépend de la police de notre système et des versions d'emoji prises en charge par cette police.
Je ne connais pas les composants internes exacts du rendu des polices et comment il peut restituer correctement les polices jointes. Ce sera peut-être un prochain article.
D'ici là, bravo ?
Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.
Copyright© 2022 湘ICP备2022001581号-3