In letzter Zeit hatte ich ein Problem mit der Anzeige von Emojis in der Benutzeroberfläche des Betriebssystems und in den Browsern meiner Fedora-Linux-Installation. Dieses Problem veranlasste mich, mich ein wenig mit dem Schriftartenkonfigurationsprojekt zu befassen, aber um meine Konfigurationen und Schriftarten zu testen, musste ich Emojis aus allen Unicode-Versionen erstellen, was mich schließlich dazu veranlasste, ein Golang-„Skript“ zu schreiben, um alle Emojis und einige davon zu drucken Informationen über ihr Inneres.
Während dieser Reise habe ich mich eingehend mit den Interna von Emojis, ihren binären Darstellungen und einigen der seltsamen/süßen Entscheidungen befasst, die der Unicode-Standard in Bezug auf Emojis getroffen hat.
Aber lassen Sie uns zunächst einen kurzen Schritt zurückgehen und einige Glossare zusammenfassen.
Wir könnten Codierung als die „Abbildung“ oder „Übersetzung“ zwischen einem Buchstaben einer Sprache und der binären Darstellung dieses Buchstabens beschreiben. Beispielsweise ordnet die herkömmliche ASCII-Kodierung den Buchstaben a der Hexadezimalzahl 0x61 zu (binär 0b01100001). Beispiele für Kodierungen sind die 8-Bit-Codepages von Microsoft (Windows 125x) oder ISO (ISO/IEC 8859).
In diesen festen 8-Bit-Codepages beträgt die minimale „Menge“ der verwendeten Informationen 8 Bit (1 Byte), was bedeutet, dass sie 256 verschiedene Buchstaben/Zeichen enthalten können. Durch die Wiederverwendung der 256 Binärcodes wurden verschiedene Codepages erstellt, um viele Sprachen zu unterstützen. Wenn also eine Textdatei mit diesen 3 Bytes geschrieben ist [0xD0, 0xE5, 0xF2], liest man sich bei Verwendung der griechischen ISO 8859-7 als „Πες“ oder bei Verwendung der westlichen ISO 8859-7 als „Ðåò“ (dieselben Bytes, unterschiedlich interpretiert). basierend auf der Codepage).
Irgendwann ließen sich viele verschiedene Codepages mit fortschreitender Technologie nicht mehr gut skalieren. Wir brauchten also etwas, das für alle Sprachen (und mehr) geeignet und systemübergreifend einheitlich ist.
[ Schneller Vorlauf, viel Geschichte und Standards weglassend, in die Gegenwart ]
Der Unicode-Standard wurde entwickelt, um alle Schriftsysteme der Welt zu unterstützen, die digitalisiert werden können. Im obigen Beispiel hat also in den Unicode-Standards der griechische Buchstabe „Π“ den Code 0x03A0, während der lateinische Großbuchstabe eth „Г den Code 0x00D0 hat und nicht mehr kollidiert. Unicode Standard verfügt über Versionen, und zum Zeitpunkt des Verfassens dieses Artikels ist die neueste Version 16.0 (Spezifikation).
Aber Moment mal, was ist das für ein „Codepunkt“?
Im Unicode-Standard hat jeder „Buchstabe“, jedes Steuerzeichen, jedes Emoji und jedes definierte Element im Allgemeinen einen eindeutigen Binärwert, der als „Codepunkt“ bezeichnet wird. Der Standard definiert alle Codepunkte und jeder Codepunkt enthält reine Code-/Binärinformationen. Das Hexadezimalformat für jeden Codepunkt wird normalerweise mit einem U-Präfix geschrieben. Der Codepunkt für den griechischen Kleinbuchstaben Omega (ω) lautet beispielsweise U 03C9.
Wer kodieren diese Codepunkte eigentlich?
Der erste Teil der Kodierung von Codepunkten in Bytes ist die Kodierungsform. Gemäß dem Standard:
Codierungsformen geben an, wie jede Ganzzahl (Codepunkt) für ein Unicode-Zeichen als Folge einer oder mehrerer Codeeinheiten ausgedrückt werden soll.
Kodierungsformulare verwenden den Begriff „Codeeinheit“, um sich auf die kleinste Dateneinheit zu beziehen, die zur Darstellung eines Unicode-Codepunkts innerhalb einer bestimmten Kodierung verwendet wird.
Der Unicode-Standard definiert drei verschiedene Kodierungsformen:
Das bedeutet, dass ein einzelner Codepunkt oder eine Folge von Codepunkten je nach verwendeter Codierungsform unterschiedlich codiert werden kann.
Die Ebene, die sich um die eigentliche binäre Serialisierung in Unicode kümmert, heißt Encoding Schemes und kümmert sich um alle Details auf niedriger Ebene (z. B. Endianness). Tabelle 2-4 der Unicode-Spezifikation:
|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 |
Hinweis: Fast alle modernen Programmiersprachen, Betriebssysteme und Dateisysteme verwenden Unicode (mit einem seiner Kodierungsschemata) als native Kodierung. Java und .NET verwenden UTF-16, während Golang UTF-8 als interne String-Kodierung verwendet (das heißt, wenn wir eine beliebige Zeichenfolge im Speicher erstellen, wird diese in Unicode mit der genannten Kodierungsform kodiert)
Der Unicode-Standard definiert auch Codepunkte für Emojis (viele davon) und (nach einigen Verwechslungen mit der Versionsnummer) schreitet die Version des Emoji-„Standards“ parallel zum Unicode-Standard voran. Zum Zeitpunkt des Schreibens haben wir Emoji „16.0“ und Unicode Standard „16.0“.
Beispiele:
⛄ Schneemann ohne Schnee (U 26C4)
? Lächelndes Gesicht mit lächelnden Augen und drei Herzen (U 1F970)
Unicode definiert Modifikatoren, die dem Basiscodepunkt eines Emojis folgen könnten, wie etwa Variation und Hautton (wir werden den Variationsteil nicht untersuchen).
Wir haben sechs Hauttonmodifikatoren (nach der Fitzpatrick-Skala) namens EMOJI MODIFIER FITZPATRICK TYPE-X (wobei x 1 bis 6 ist), und sie wirken sich auf alle menschlichen Emojis aus.
Heller Hautton (Fitzpatrick Typ 1-2) (U 1F3FB)
Mittelheller Hautton (Fitzpatrick Typ 3) (U 1F3FC)
Mittlerer Hautton (Fitzpatrick Typ 4) (U 1F3FD)
Mitteldunkler Hautton (Fitzpatrick Typ 5) (U 1F3FE)
Dunkler Hautton (Fitzpatrick Typ 6) (U 1F3FF)
Also zum Beispiel, wie alle menschlichen Emojis, das Baby-Emoji? (U 1F476) erscheint, wenn kein Hautmodifikator folgt, in einer neutralen gelben Farbe. Wenn dagegen ein Hautfarbmodifikator folgt, ändert er sich entsprechend.
? U 1F476
?? U 1F476 U 1F3FF
?? U 1F476 U 1F3FE
?? U 1F476 U 1F3FD
?? U 1F476 U 1F3FC
?? U 1F476 U 1F3FB
Die seltsamste, aber niedlichste Entscheidung des Emoji/Unicode-Standards ist, dass einige Emojis definiert wurden, indem andere mithilfe des Zero-Width-Joiners ohne einen eigenständigen Codepunkt zusammengefügt wurden.
Also zum Beispiel, wenn wir Folgendes kombinieren:
Weiße Flagge ?️ (U 1F3F3 U FE0F)
Nullbreitenverbinder (U 200D)
Regenbogen? (U 1F308)
Es erscheint als Regenbogenflagge ?️? (U 1F3F3 U FE0F U 200D U 1F308)
Oder, ?? ? => ???
Oder sogar, ?? ❤️ ? ?? => ??❤️???
Es ist, als würde man Emojis zusammendrücken und dann, puh?, erscheint ein neues Emoji. Wie süß ist das?
Ich wollte eine Markdown-Tabelle mit allen Emojis erstellen, und die Unicode-Emoji-Sequenztabellen sind die Quelle der Wahrheit dafür.
https://unicode.org/Public/emoji/16.0/emoji-sequences.txt
https://unicode.org/Public/emoji/16.0/emoji-zwj-sequences.txt
Also habe ich einen Golang-Parser (hier) erstellt, der diese Sequenzdateien abruft und analysiert, jedes Emoji generiert, wenn ein Bereich in der Sequenzdatei beschrieben wird, und eine Markdown-Tabelle mit einigen internen Informationen für jede einzelne ausgibt (wie Teile, falls es zusammengefügt wurde, oder der Grundton Hautton usw.).
Die Markdown-Tabelle finden Sie hier.
Die letzte Spalte dieser Tabelle hat das folgende Format:
str := "⌚" len([]rune(str)) // 1 len([]byte(str)) // 3
Wie wir besprochen haben, ist die interne String-Kodierung von Golang UTF-8, was bedeutet, dass beispielsweise für Uhr-Emoji ⌚ die Bytelänge 3 beträgt (da UTF-8 3 Bytes erzeugt, um diesen Codepunkt zu „schreiben“), und die Codepunktlänge ist 1.
Golang-Rune == Unicode-Codepunkt
Aber im Fall von verbundenen Emojis – selbst wenn sie als eins „erscheinen“ – haben wir viele Codepunkte (Runen) und noch mehr Bytes.
str := "??❤️???" len([]rune(str)) // 10 len([]byte(str)) // 35
Und der Grund ist, dass:
??❤️??? : ?? 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]
?
Es ist erwähnenswert, dass die Art und Weise, wie wir Emojis sehen, von unserer Systemschriftart abhängt und davon, welche Emoji-Versionen diese Schriftart unterstützt.
Ich kenne die genauen Interna der Schriftartenwiedergabe nicht und weiß nicht, wie die verbundenen Schriftarten korrekt wiedergegeben werden können. Vielleicht wird es ein zukünftiger Beitrag sein.
Bis dahin, Prost?
Haftungsausschluss: Alle bereitgestellten Ressourcen stammen teilweise aus dem Internet. Wenn eine Verletzung Ihres Urheberrechts oder anderer Rechte und Interessen vorliegt, erläutern Sie bitte die detaillierten Gründe und legen Sie einen Nachweis des Urheberrechts oder Ihrer Rechte und Interessen vor und senden Sie ihn dann an die E-Mail-Adresse: [email protected] Wir werden die Angelegenheit so schnell wie möglich für Sie erledigen.
Copyright© 2022 湘ICP备2022001581号-3