Alexis Bingessners Artikel
"Text Rendering Hates You", der vor einem Monat veröffentlicht wurde
, steht mir sehr nahe.
Im Jahr 2017 entwickelte ich einen interaktiven Texteditor in einem Browser. Unzufrieden mit den vorhandenen ContentEditable-Bibliotheken dachte ich: „Hey, ich realisiere nur die Auswahl des Textes neu! Ist es schwer? " Ich war jung Naiv. Ich dachte mir, dass ich in zwei Wochen damit fertig werden könnte. Tatsächlich dauerte der Versuch, dieses Problem zu lösen, mehrere Jahre meines Lebens, einschließlich eines Jahres bezahlter Arbeit von morgens bis abends, um einen Texteditor für das neue Betriebssystem zu entwickeln.
Bei der Arbeit hatte ich das Glück, viel von
Mentoren mit großer Erfahrung auf diesem Gebiet zu lernen. Ich habe viele, viele Gruselgeschichten gehört. Einschließlich eines Ingenieurs, der eine Windows-Anwendung mit einer benutzerdefinierten Implementierung eines Textfelds unterstützte und von einer veralteten Texteingabe-API zu einer neuen Version wechseln wollte. Hier ist eine
Liste der Texteingabeschnittstellen in dieser neuen Version:

Das ist richtig, 128 Schnittstellen zur Texteingabe. Ich bin mir fast sicher, dass es acht (8!) Verschiedene Arten von Sperren gibt, um Parallelitätsprobleme zu beheben, obwohl ich deren Dokumentation ehrlich gesagt nicht gelesen habe. Zitieren Sie mich daher nicht dazu. Dieser Ingenieur hat anderthalb Jahre (Vollzeit!) Seinen Editor geändert, ist aber am Ende gescheitert und auf der alten API geblieben.
Das Tippen ist schwierig.
Alexis erwähnt manchmal die Auswahl von Text, aber ihre persönliche Erfahrung hängt mehr mit dem Rendern zusammen. Andererseits kann ich als Person einige Punkte zur Eingabe hinzufügen.
Vertikale Cursorbewegung
Ich habe dies bereits in einem
früheren Artikel behandelt , aber wir können es hier schnell wiederholen.
Wenn Sie in diesem Beispiel nach oben drücken, bewegt sich der Cursor an den Zeilenanfang vor dem Wort
Hallo . Bisher ist alles ziemlich vernünftig. Wenn Sie jedoch nach oben und unten drücken, springt der Cursor zuerst vor
Hallo und steht dann nach
einigen .
Dies mag nicht sehr logisch erscheinen. Sie fragen, warum er nach rechts springt? Bei vertikalen Bewegungen merkt sich jeder Cursor die
x- Position in Pixel und wird nur aktualisiert, wenn er nach links oder rechts gedrückt wird und nicht nach oben und unten. Das gleiche Verhalten verhindert, dass sich Cursor nach links bewegen, wenn sie sich vertikal durch kurze Linien bewegen.
Nähe
Okay, jetzt wissen wir, dass wir bei der Auswahl von Text
zwei Statuselemente haben: den oben erwähnten Byte-Versatz innerhalb der Linie und die
x- Koordinate in Pixel. Das Problem ist gelöst? Nun, nein.
Betrachten Sie zwei Cursorpositionen in einer sehr langen Zeile:
Da
loooooooooong ein Wort ist, haben zwei Cursorpositionen
genau den gleichen Byte-Offset in der Zeichenfolge . Es gibt keine neue Zeile zwischen ihnen, da die Zeile weich umwickelt ist. Unsere Cursor benötigen ein zusätzliches Bit, das ihnen sagt, zu welcher Zeile sie gehen sollen. Die meisten Systeme nennen dieses Bit Affinität. Es wird auch in gemischtem bidirektionalem Text verwendet, über den wir bald sprechen werden.
Emoji-Modifikatoren
Angenommen, ich sende eine Nachricht an einen Freund. Um meine Gefühle auszudrücken, möchte ich ein lustiges Emoji hinzufügen. Ich gebe im Textbereich einen Daumen nach oben, einen Buchstaben
a
und einen Emoji-Modifikator für den Hautton ein. Es sieht so aus:
Oh, ich wollte keinen Brief schreiben. Ich setze den Cursor danach und klicke auf Rücktaste. Was wird passieren? Ich habe je nach Editor mehrere Optionen gesehen.

- Schlechte Nummer 1 scheint richtig zu sein. Auf diese Weise funktioniert ein Texteditor mit Unterstützung für Legacy-Emoji-Rendering, z. B. Sublime Text. Dies ist schlecht, da das leichte Finger-Emoji als gelber Finger codiert wird, gefolgt von einem Hauttonmodifikator. Sie werden nicht wie erwartet zu einem Symbol zusammengefasst. Selbst wenn ich den Lichtfinger aus einer anderen Anwendung kopiere, wird er wie hier nicht richtig angezeigt.
- Schlechte Nummer 2 ist das, was Chrome 77 in der Adressleiste tut. Nicht auf Webseiten, sondern nur in der Adressleiste. Dies ist kein Rendering-Problem, da das Kopieren und Einfügen von Emoji mit Hautton funktioniert. Stattdessen löscht Chrome den Buchstaben. Nachdem Sie den Modifikator nach dem Buchstaben bemerkt haben, wird er auch gelöscht. Hoppla!
- Bad # 3 entspricht der Unicode-Spezifikation, wie Emoji zusammengeführt werden soll. Für Benutzer ist dies jedoch nicht nachvollziehbar. Übrigens müssen Sie den Cursor bewegen, damit er nicht auf halber Strecke im Emoji hängen bleibt.
Alle Optionen sind schlecht, daher können Sie davon ausgehen, dass es wahrscheinlich eine vierte Option gibt. Gibt es! In vielen Editoren, wie z. B. TextEdit, können Sie den Cursor nicht einmal nach dem Buchstaben setzen, da der Hauttonmodifikator als eine Einheit mit dem vorherigen Zeichen betrachtet wird. Dies ist im Kontext von Emoji sinnvoll und funktioniert in diesem Fall sogar gut. Was ist jedoch, wenn der Modifikator durch das erste Zeichen in der Zeichenfolge angezeigt wird?
Jetzt ändert der Modifikator das Zeilenumbruchzeichen. Mit TextEdit können Sie den Cursor nicht am Anfang der zweiten Zeile platzieren! Ich persönlich halte diese Entscheidung für „auch schlecht“.
Möglicherweise haben Sie auch bemerkt, dass der Daumen nach oben zum Daumen nach unten geworden ist. Ich habe dies selbst getan, um meine Gefühle über die gesamte Situation zu reflektieren.
TextEdit macht den Cursor in der ersten Zeile übrigens
sehr fehlerhaft. Ratet mal, was passiert, wenn ich hier
4
drücke?
Ja. Sie könnten auch denken, dass zwischen den Zahlen Leerzeichen stehen. Sie sind nicht da.
Bidirektionaler Text
Alexis erwähnt geteilte Auswahlen in gemischtem bidirektionalem Text, wie in diesem Beispiel aus TextEdit:
Dies ist wirklich sinnvoll, da die arabische Sprache in den Zeilen von rechts nach links codiert ist, so dass die Auswahl geteilt zu sein scheint, aber Bytes ein kontinuierlicher Bereich sind.
Daher ist es ein wenig überraschend, dass wir diese Auswahl erhalten können:
Ja, es ist visuell kontinuierlich, aber bytegetrennt. Ja, es ist schlecht. Einige Editoren tun dies, wenn Sie Text mit den Pfeiltasten anstelle der Maus auswählen. Eine Alternative besteht darin, die linke / rechte Taste im Text mit der Richtung von rechts nach links zu tauschen, was ebenfalls schlecht ist. Hier gibt es keine guten Möglichkeiten.
Versuchen Sie als Bonus zu verstehen, was hier vor sich geht:
Herr ... Ich möchte das nicht kommentieren.
Die Sache mit den Eingabemethoden
Software, die Tastenanschläge in Eingaben übersetzt, wird als Eingabemethode oder Eingabemethodeneditor bezeichnet. Für das lateinische Alphabet ist dies keine sehr interessante Software, da jeder Tastendruck direkt mit dem Einfügen eines Zeichens verbunden ist. In vielen Skripten passen Zeichen jedoch nicht auf die Tastatur, daher müssen Sie kreativ sein. Bei einigen Eingabemethoden für die chinesische Sprache gibt der Benutzer beispielsweise Töne ein - und erhält eine Liste von Zeichen, deren Ton ähnlich ist:
Dieses Feld wird manchmal als Erstellungsbereich bezeichnet und erscheint häufig
über dem unterstrichenen Text . Manchmal muss die Eingabemethode sie formatieren. Beispielsweise verwendet die japanische Eingabemethode unter Android die Hintergrundfarbe, um einen Bereich für die gemeinsame Nutzung von Sätzen zu erstellen:
(Danke an Shae für den Screenshot!)Interagieren all diese Auswahlen und Kompositionsbereiche mit bidirektionalem Text? Denken wir nicht darüber nach.
Eingabemethoden sollten überall funktionieren,
auch innerhalb des Terminals :
Vim wird erst dann benachrichtigt, wenn ein chinesisches Schriftzeichen aus der Liste ausgewählt wurde. Sie denken wahrscheinlich: "Aber wie funktioniert es im Vim-Befehlsmodus?" Nicht sehr gut. Aus diesem Grund sind Texteingabe und Tastenanschläge im Internet separate Ereignisse. In der Konsole mischen sie sich und verursachen Probleme.
Dies ist nur ein Beispiel für viele verschiedene Texteingabemethoden. (Vergessen Sie nicht die Eingabemethoden ohne Tastatur wie Sprache und Handschrift!) Glücklicherweise bietet Ihnen das Betriebssystem all diese Methoden. Leider sollte Ihr Textfeld das allgemeine Texteingabeprotokoll sprechen, das von all diesen Methoden verwendet wird. Für Windows sind dies die 128 Schnittstellen, die am Anfang des Artikels aufgeführt sind. In anderen Betriebssystemen sind Schnittstellen einfacher, aber immer noch schwer zu implementieren.
Möglicherweise stellen Sie auch fest, dass die Eingabemethode ein separater Prozess ist, sodass sowohl die Eingabemethode als auch die Anwendung Änderungen am Status des Textfelds vornehmen können. Dies ist eigentlich ein paralleles Bearbeitungsprotokoll. Windows löst das Problem mit acht (8!) Arten von Sperren. Obwohl das Halten einer Sperre über Prozessgrenzen hinweg zweifelhaft erscheint, versuchen die meisten anderen Plattformen, unvollständige Heuristiken zu verwenden, um Parallelitätsprobleme zu beheben. Oder sie hoffen nur, dass die Rennbedingungen nicht eintreten. Nach meiner Erfahrung ist das Gebet kein sehr wirksames Primitiv der Parallelität.
Warum ist alles so kompliziert?
Jonathan Blow erwähnt in einem Vortrag über Software-Degradation den
Texteditor Ken Thompson , den er in einer Woche geschrieben hat. Der größte Teil des Codes in diesem Artikel ist zufällig eingeführte Komplexität. Benötigt Windows wirklich 128 Schnittstellen und 8 Arten von Sperren für die Texteingabe? Auf keinen Fall. Sind Fehler in TextEdit das Ergebnis eines komplexen Bearbeitungsmodells? Ja Ist die Streuung von Fehlern in modernen Programmen ein Grund zur Sorge? Zumindest für mich ist es das.
Ken Thompsons Editor war jedoch auch viel, viel einfacher als das, was wir von modernen Texteditoren erwarten. Unicode unterstützt fast alle lebenden Sprachen der Welt (es gibt ungefähr 7.000 davon), und viele weitere sind tot. Es gibt verschiedene Skripte, Textrichtungen und Eingabemethoden, von denen jede jedem Editor komplexe (und in einigen Fällen unlösbare) Einschränkungen auferlegt. Er muss aber auch Screenreader unterstützen.
Es entsteht
unweigerlich eine enorme Komplexität, die wir in diesem Artikel nur geringfügig berührt haben. Dies ist ein echtes Programmierwunder, bei dem Sie einfach
<textarea>
auf eine Webseite schlagen und sofort jedem Internetbenutzer auf der ganzen Welt eine Texteingabe bereitstellen können.