Sonntag, 27. Mai 2012

Das Problem mit dem heutigen Internet

Das Internet ist langweilig. Sie durchforsten die Nachrichten. Sie sehen ein lustiges Kätzchen auf YouTube oder aktualisieren Ihren Status, aber anders als, sagen wir, eine Reise in die Antarktis oder einfach mal eben einen Spaziergang in der Nachbarschaft zu unternehmen, fehlt dem Internet etwas...

Das Internet ist großartig, wenn Sie nach etwas suchen, aber was, wenn Sie nicht genau wissen, wonach Sie suchen?

In einem Szenario des echten Lebens könnten Sie manchmal einfach rausgehen, einen Spaziergang machen, umherwandern und sich selbst in einem kleinen Buchladen am Ende der Straße wiederfinden. Ein Internet-Szenario wäre: Sie googeln "Buchladen" und folgen einem Link... also, die heutige Internet-Erfahrung ist so ziemlich, wie eine Augenbinde zu tragen. Sie beginnen irgendwo und dann, wenn Sie weiterkommen wollen, brauchen Sie Hilfe (die einer Suchmaschine oder die Kenntnis der Adresse der Webseite) um von dort, wo Sie genau jetzt sind, direkt zu Ihrem nächsten Bestimmungsort zu springen (oder dahin getragen zu werden). Da Sie dies mit verbundenen Augen tun, verpassen Sie die Erfahrung, sich wirklich von einem Ort zum nächsten zu begeben und Sie können sich nicht auf dem halben Weg zu Anhalten entschließen, nur weil Sie etwas anderes sehen, das Ihnen gefällt.

Da Sie einfach von einem Ort zum nächsten springen, als wenn es keine Entfernungen gäbe, ist es so, als wenn sich die Reise von Los Angeles nach Neuseeland genauso anfühlt, wie die Reise nach San Francisco. Ihre Nutzererfahrung ist das direkte Ergebnis des Ortes, den Sie besuchen, was Sinn macht, aber andere Faktoren ermangelt, wie beispielsweise die Länge der Reise und wie einfach oder erschöpfend es war, dort hin zu gelangen.

Also, auf der einen Seite macht es das Internet zu leicht, von einem Ort zum anderen zu springen und auf der anderen Seite ist es unmöglich, wirklich die Strecke zwischen zwei Webseiten zurückzulegen, eine wirkliche Reise zu erfahren, mit aufregenden Plätzen entlang des Weges.

[/caption]

Die fehlende Zutat

Also, was ist diese Zutat, welche dem Internet fehlt? Nun, Sie können sie räumliche Orientierung nennen.
Wenn Sie auf eine Reise gehen, passieren Sie auf Ihrer  Route viele Plätze, einige von den sind interessanter und einige sind weniger interessant. Wenn Sie fragen, was die - sagen wir mal zwei - Plätze, die Sie passieren gemeinsam haben, von denen einer der Betrachtung nicht wert, aber der andere so interessant ist, dass Sie sich entschließen, dort mehrere Stunden oder Tage zu verbringen.
Die Antwort ist, beide sind dort. Um den Begriff "dort" auf das Internet zu reflektieren, müssen Sie einen Raum ähnlich dem der realen Welt kreieren.
Nein. Ich spreche nicht von einem neuen Virtual Reality Spiel... "Virtuell" ist etwas, das nicht real ist, aber das Internet ist real. Es muss nicht zu einer altenativen "realen Welt" werden, aber es sollte eine neue und einzigartige Welt (oder Universum) werden.
Einige der Eigenschaften in unserer Welt sind willkürlich, aber das ist es, was unsere Welt aufregend, unvorhersehbar und sich dauernd erneuernd macht. Viele Dinge, die Sie erfahren, passieren "durch Zufall". Sie treffen jemanden durch Zufall. Sie entdecken einen wunderschönen Ort durch Zufall.
Um zurück auf das Beispiel mit dem Buchladen zu kommen, wenn Sie diesen kleinen Buchladen entlang Ihrer Route gefunden haben, dann mussten Sie nicht "Bücher" googeln. Er war einfach dort.
Es gab viele Versuche dem Internet eine "Raum" Dimension als Attribut hinzuzufügen, aber in den meisten Fällen war der Raum eine direkte Widerspiegelung von Geodaten, übernommen aus der realen Welt. Google Street View ermöglicht Ihnen zu reisen, als ob Sie wirklich reisen würden.

Aber das Internet verdient seine eigene Existenz; es verdient seinen eigenen Raum. Es ist großartig, das Reisen, Fliegen, Autofahren und das Treffen von Leuten in Ihrer Gegend zu simulieren, aber wäre es nicht noch großartiger, wirklich durch das Internet zu reisen, als eine Realität und nicht als eine Simulation einer anderen Realität?

Um dies wahr zu machen, müssen wir den Webseiten willkürlich einen Platz in diesem Raum zuweisen (was auf "wer zuerst kommt, mahlt zuerst" basieren könnte), aber mit der Fähigkeit sich "physisch" von einem Ort zum nächsten zu bewegen, ähnlich einem Spaziergang.

Reisen durch das Internet

Das Übertragen des Internets in einen neuen und einzigartigen Raum, mit Entfernungen, Pfaden und seiner eigenen, räumlichen Orientierung wird das wahre Potential des Internets entfesseln. Stellen Sie es sich so vor: Warum sind wir so abhängig von Suchmaschinen (z.B. Google ...)? Warum können wir nicht einfach durch das Internet reisen?

Die Erschaffung eines solchen Raumes muss damit beginnen, dass man ihm willkürliche Attribute zuweist, welche später eine stärkere Bedeutung erhalten. Es wäre ähnlich wie die Bevölkerung der Erde vor Millionen von Jahren, verglichen mit heute, wo es einen signifikanten Unterschied zwischen dem Leben (oder Aufsuchen) eines Ortes verglichen mit einem anderen oder dem Finden eines Hauses im Stadtzentrum verglichen mit den Vororten gibt.

Weiterhin sollte es mehr als einen Weg zu reisen geben. Nicht nur Googeln, sondern die endlos potentielle Möglichkeit des einfachen Umherwanderns. Im Ergebnis wird die Internet-Erfahrung Sie Orte besuchen lassen, die Sie eigentlich nicht planten zu besuchen. Dies wird den Besuch von Orten einschließen, nur weil sie nahe bei einem anderen Ort liegen, den Sie eigentlich besuchen wollten und der Begriff "nahe liegen" wird mit Hilfe eines neuen Zuordnungssystems eingeführt werden müssen und nicht irgendwelche existierenden, aus der realen Welt importierten geografischen Systeme widerspiegeln.

Das wird dem Internet geben, was es verdient - seine eigene Existenz als Kosmos
Natürlich, so wie wir begeistert wären, in der Lage zu sein von LA nach Neuseeland innerhalb eines Sekundenbruchteils zu springen, werden die alten Wege zum Erfahren des Internets noch verfügbar sein und werden wie zuvor genutzt, aber es ist Zeit, diese fehlende Zutat dem Internet hinzuzufügen, damit es ein eigenständiges Universum wird.

Zusätzliche Richtungen

Das Universum, welches innerhalb der Existenz des Internets eingekapselt ist, hat eine Menge mit unserem eigenen Universum gemein, welches zu der Idee führt, die Lücke der räumlichen Orientierung zu schließen, aber es gibt auch großes Potential für Attribute, welche nicht Teil unserer eigenen Welt sein können, wie beispielsweise Zeitreisen.
Reisen durch das Internet kann kann auf eine bestimmte Zeit oder einen bestimmten Zeitabschnitt (zum Beispiel das 20. Jahrhundert) gefiltert werden. Wenn das Browsen des Internets eine Erfahrung ähnlich dem Bereisen und Entdecken neuer Welten werden kann, kann solch ein Filter diese Erfahrung zu einer Reise durch die Zeit mit einer Zeitmaschine machen.

Neue Geschäftsmodelle

Zusätzlich wird dem Internetreisenden eine Auswahl an Transportmitteln zur Verfügung stehen, was nicht nur die einschränkende Abhängigkeit von Suchmaschinen beenden wird, sondern auch die Möglichkeit beinhaltet, zu wählen, wie man reist. Dies wird neue Geschäftsmodelle keieren: Schnell; Langsam; Direkt; oder mit vielen Haltestellen auf der Route. Zum Thema neue Geschäftsmodelle; heute basieren alle internetbezogenen Geschäftsmodelle auf dem Besuch und dort ist die neue Möglichkeit, hier neue Geschäftsmodelle zu kreieren, die auf der eigentlichen Reise von einer Webseite zur nächsten basieren. Basierend auf solchen Modellen wäre typischerweise das Publikum einer Webseite Ihre Nachbarschaft (Umkreis um Sie herum) und würde einer solchen kostenlos zur Verfügung stehen, während Kosten entstehen könnten, wenn es zu einer längeren Reise kommt, basierend auf der Internetentfernung, welche sich auf die neue Art bezieht, in der das Internet kartografiert wird.

Die Nachbarschaft

Durch das Hinzufügen von räumlicher Orientierung zum Internet und durch das Zusammenfassen von Webseiten in Orte, ähnlich den Nachbarschaften, Städten, Staaten, Ländern und Kontinenten, wird eine typische "Internetstadt" Webseiten unterschiedlicher Natur haben, welche nebeneinander residieren. Solche Seiten könnten ein Bücherladen, eine Reiseagentur (die "kommerzielle Gegend" Ihrer Stadt), mehrere persönlichen Blogs (die "Wohngegend" Ihrer Stadt), Museen, Nachrichtenagenturen etc. sein, welche alle die gleiche Nachbarschaft teilen. Die realen Leute und Organisationen hinter diesen Webseiten könnten aus der ganzen Welt kommen, obwohl diese Webseiten der gleichen Stadt zugeordnet sind. Ungleich Unternehmen, welche darauf abzielen, Aktivitäten über das Web auf geografische Orte zu beziehen, zum Beispiel dem Endnutzer zu sagen, wer sich in seiner oder ihrer Gegend befindet (Freunde, Restaurants etc.), handelt diese Idee davon, dem Internet seine eigene geografische Domain zu ermöglichen, mit Orten, Entfernungen und der Fähigkeit zu reisen und sie zu entdecken, egal wo Sie sich in der realen Welt befinden.
Also eine solche Stadt wird diese Seiten, eine neben der anderen haben als ein Ergebins von "Angebot und Nachfrage". Zuerst wird das gesamte Universum zur Besiedlung frei sein und wie die alten Entdecker, werden die Leute die Möglichkeit haben, sich an jedem Platz anzusiedeln und Gemeinschaften direkt neben anderen Leuten und Firmen zu bilden, aber die Heterogenität, welche die Kernidee in diesem Artikel ist, wird alle Arten von Unternehmen, Geschäften und Leuten in die gleiche Gemeinschaft bringen.
In der echten Welt, kann jemand einen Friseurladen neben einem Internetcafe oder einem Coffeeshop eröffenen, obwohl sie nichts gemeinsam haben, außer dass sie willkürlich nebeneinander residieren. Nebeneinander zu residieren, ohne den gleichen Inhalt, ISP, Publikum, Herkunftsland und sogar Sprache zu teilen.. all dies sollte diese Webseiten nicht daran hindern, in der gleichen Internet-Nachbarschaft zu residieren.


Die Fähigkeit, Webseiten "nahe beieinander" oder "neben einander" zu haben, mit der Fähigkeit, dem Endnutzer die Erfahrung des Umherwanderns und Reisen durch das Internet bei geringerer Abhängigkeit von Suchmaschinen bereitzustellen, ist im Grunde das, was dem heutigen Internet fehlt.

Entwicklung von Rashumon - Die Geheimnisse

Als ich Rashumon entwickelte, gab es keine Unterstützung für mehrsprachige / bidirektionale Texte und ich musste diese von Grund auf neu programmieren.

Hintergrund

Während der Jahre 1989 bis 1994 entwickelte ich Rashumon, das erste mehrsprachige, grafische Textverarbeitungsprogramm für den Amiga. Rashumon brachte einige einzigartige Funktionen:
  • Mehrfache Auswahl von Text (gleichzeitige Auswahl von nicht zusammenhängenden Textteilen)
  • Tabellengenerator
  • Unterstützung mehrfacher Tastaturbelegungen (bis zu 5 gleichzeitig)
  • Suchen und Ersetzen einschließlich Farbe, Stil und Fontfilter
    Rashumon - Search / Replace
  • Mehrsprachige String Gadgets zur Erzeugung und Umbenennung von Dateien, Schubladen etc.
  • Import und Export mehrsprachiger ASCII Dateien von und zu PC und MAC
  • Ultraschnelle Bildschirmaktualisierung und Scrolling
  • IFF Grafik Unterstützung (Import und Export)
  • Direkter Zugriff auf jedes der 256 Zeichen jedes einzelnen Fonts

Verwendung des Codes

Die in diesem Artikel verwendeten Codebeispiele wurden aus dem Rashumon Sourcecode entnommen und können von jedem C++ Compiler geprüft werden, obwohl sie für den Amiga Aztec C compiler erstellt wurden.

Sehenswertes

Heutzutage neigen wir dazu, einiges von der Komplexität zu vergessen, welche Teil des Progammierens vor 20 Jahren war und heute als Teil im SDK eines jeden Betriebssystems mit eingebaut ist, darunter: bidirektionales Editieren, Textbearbeitung im Allgemeinen, Scrollen von Text und Zeilenumbrüche. Die Entwicklung eines mehrsprachigen Textverarbeitungsprogramm für den Amiga damals in 1989, erforderte in der Tat, das Schreiben von Teilen, die heute Teil eines Betriebssystems sind, aber damals fehlten.

Entwicklung von  Rashumon

Der Amiga war und ist noch immer ein großartiger Computer mit großartigen Fähigkeiten, insbesondere wenn es um Sound und Video geht. Wie dem auch sei, grundlegende Element, wie eine Dateiauswahl-Dialogbox fehlten, ganz zu schweigen vom Support für linksläufige Sprachen. Heute beinhalten alle Betriebssysteme die notwendigen Kernelemente, um mehrsprachige Textbearbeitung zu unterstützen. Der Text wird in der Reihenfolge abgespeichert, in der er geschrieben wurde und rückwärts angezeigt, wenn es sich um eine linksläufige Sprache handelt. Dies macht das Editieren und Manipulieren einfach und leicht, da der Speicher die logische Reihenfolge des Textflusses widerspiegelt. Damals war es notwendig, solche Bausteine zu entwickeln und es hätte meine Textverarbeitung zu langsam gemacht, wenn ich den Text anders dargestellt hätte, als er abgespeichert wurde. Stattdessen wollte ich meinen eigenen Zeilenumbruchmechanismus entwickeln. Zeilenumbruch ist der Mechanismus, der das Umbrechen der Zeilen erlaubt, ohne die Wörter zu zertrennen. Anders als die alte Schreibmaschine, wo man an das Ende einer Zeile kommt und manchmal ein Wort in der Mitte trennen muss, sind Textverarbeitungsprogramme in der Lage, das zuletzt geschriebene Word in die nächste Zeile zu verschieben, sollte in der aktuellen Zeile nicht genug Platz sein. Dies wird sogar noch komplexer, wenn man es mit proportionalen Schriften zu tun hat, bei denen jeder Buchstabe seine eigene Breite hat und wenn man die Kombination mehrerer Fonts erlaubt. All dies war nicht Teil einer hochentwickelten API, aber erforderte die Berechnung der voraussichtlichen Länge eines gegebenen Textes in Pixeln, unter Berücksichtigung jeder Buchstabenbreite basierend auf dem Buchstaben, dem Font, dem Attribut (fett, kursiv) und der verwendeten Größe zusammen mit den gewählten Rändern. Selbst wenn wir es nur mit einer Richtung (links nach rechts) der Bearbeitung zu tun haben, war das immer noch kompliziert von Grund auf zu programmieren. Für den Anfang, schrieb ich eine Routine, um die Länge einer gegebenen Zeile zu berechnen:

int LLen=(mode==GRAPHICS)?ln->Len:(ln->CharLen=strlen(ln->Txt))*8;

Wie Sie sehen können, ist dies ein einfaches Szenario wo "mode" ungleich "GRAPHICS" ist, dann wird die Länge auf Basis der Zeichenanzahl multipliziert mit 8 berechnet (was die Länge eines jeden Zeichens bei unproportionalen Schriften ist). Wenn es an die Bearbeitung bidirektionaler Texte unter Verwendung proportionaler und unterschiedlicher Fonts geht, ist es komplizierter sogar einen einzelnen Buchstaben einzufügen:

// Dies ist eine Routine für das Hinzufügen eines einzelnen Characters, entnommen vom Rashumon Quellcode

static put_char(wrap,chr)
BOOL wrap;
UBYTE chr;
{
       UBYTE c[2];
       BOOL update=FALSE;

       c[1]='\0';
       c[0]=chr;
       if(ENGLISH_H) // Left to right text
       {
              if(chr>='a'&& chr<='z' && map[Header->format >> 11]<2) chr=ucase(chr);
              if(Header->Insert || !HCL->Txt[CR])
              {
                     if(!wrap && HCL->Len+font_width(HCL,CR)>HCL->MaxLen) return();
                     char_insert(HCL,c[0],CR);
                     HCL->CharLen++;
                     CR++;
                     HCL->Len+=font_width(HCL,CR-1);  
// Hier addieren wir die zusätzliche Größe zur gesamten
// Zeilenlänge in Pixeln
                     HCL->CursLen+=font_width(HCL,CR-1);
              }
              else /* ÜBERSCHREIBEN IN ENGLISCH */
              {
                     // Nun behandeln wir den Überschreibemodus
                     HCL->Txt[CR]=c[0];
                     HCL->Format[CR]=Header->format;
                     if(c[0]==9)
                     {
                           SetFlag(HCL->Format[CR],TAB);
                           HCL->Txt[CR]=SPACE_CHR;
                           SetFlag(MD,TABS);
                     }
                     CR++;
                     calc_charlen(HCL);
                     calc_all(HCL);
                     Clear(HCL);
              }
       }
       else
       // Hebräischer ( oder Rechts nach Links) Modus
       {
              if(!Header->Insert && CR)
              {
                     CR--;
                     HCL->CursLen-=font_width(HCL,CR+1);
                     HCL->Txt[CR]=c[0];
                     HCL->Format[CR]=Header->format;
                     if(c[0]==9)
                     {
                           SetFlag(HCL->Format[CR],TAB);
                           HCL->Txt[CR]=SPACE_CHR;
                           SetFlag(MD,TABS);
                     }
                     calc_all(HCL);
                     Clear(HCL);
              }
              else
              {
                     if(!wrap && HCL->Len+font_width(HCL,CR)>HCL->MaxLen) return();
                     char_insert(HCL,c[0],CR);
                     HCL->Len+=font_width(HCL,CR);
                     HCL->CharLen++;
              }
       }
       if(HCL->Mode & TABS) calc_all(HCL);
       if(c[0]!=SPACE_CHR && fonts[Header->format >> 11]->tf_YSize>LH(HCL))
       {
              HCL->LineHeight=Header->LineHeight=fonts[Header->format >> 11]->tf_YSize;
              HCL->BaseLine=Header->BaseLine=fonts[Header->format >> 11]->tf_YSize-fonts[Header->format >> 11]->tf_Baseline;
              update=TRUE;
       }
       else
       if(c[0]==SPACE_CHR && HCL->prev && !(HCL->Mode & PAR) && wrap)
       {
              WrapLine(HCL->prev,!(update));
       }
       if(HCL->Len<=HCL->MaxLen && !(update))
       {
              showtext(HCL);
              SetCursor();
       }
       else
       if(wrap)
              FixLine(HCL,!update);

       if(update)
              update_lh(HCL,TRUE);


}


Der nächste Schritt war das Durchführen des Zeilenumbruchs bei bidirektionalen Zeilen. Wie ich erklärte, wurden die Zeilen so dargestellt, wie sie im Speicher abgelegt waren. Der Text  "abcאבג" wurde exakt so abgespeichert, wie er aussieht. Rashumon verwendete Doppelbyte-Zeichen, was bedeutet, dass jedes Zeichen unter Verwendung von 2 Bytes abgespeichert wurde. Dies war, bevor UNICODE erfunden wurde, also war das erste Byte ausreichend um jedes Zeichen in jeder unterstützten Sprache zu speichern. Zu dieser Zeit gab es ASCII-Zeichen in zwei Formen, eine nutzte die Werte von 0 bis 127 und die erweiterte Form nutzte die Werte 0 bis 255. Ich verwendete die erweiterte Form und musste entscheiden, wo die linksläufigen Sprachen zu platzieren waren.

Es gab keinen Standard für linksläufige Sprachen. IBM verwendete die Stellen 128 bis 154, aber ich fand dies problematisch und wählte die Stellen ab 224, was heute die richtige Wahl zu sein scheint, da dies identisch mit der heutigen Darstellung von linksläufigen Sprachen unter Verwendung von 2 Byte Codierungen ist. Also falls ich ein Diskettenimage von 1989 (.ADF-Datei) öffne, erscheinen alle hebräischen Rashumon Dokumente in der korrekten Codierung.

Was das zweite Byte angeht, dies wurde verwendet, um die Zeichenfarbe abzuspeichern (3 Typen, bedeuten bis zu 8 Farben), die Zeichenattribute (fett, kursiv und unterstrichen oder jede Kombination dieser 3), Sprache (links- oder rechtsläufig) und den Font durch Verweis auf einen Index des Fonts innerhalb einer lokalen Liste, die aus der Gesamtliste der verwendeten Fonts für jedes Dokument erstellt wurde.

/* Line structure */
#define COLOR_BIT_1 1             /* 1  */
#define COLOR_BIT_2 2             /* 2  */
#define COLOR_BIT_3 4             /* 3  */
#define UNDL 8                    /* 4  */
#define BOLD 16                   /* 5  */
#define ITAL 32                   /* 6  */
#define SELECT 64          /* 7  */
#define LANG 128           /* 8  */
#define TAB 256                   /* 9  */
#define UNUSED_1 1024             /* 10 */
#define UNUSED_2 2048             /* 11 */
#define FONT_BIT_1 4096    /* 12 */
#define FONT_BIT_2 8192           /* 13 */
#define FONT_BIT_3 16384   /* 14 */
#define FONT_BIT_4 32768   /* 15 */
#define FONT_BIT_5 65536   /* 16 */


Tastenbelegung und Codierung

Die Tastenbelegung wurde als ein Array aller Zeichen je Platz beginnend bei "1" und bis zum Ende des Arrays verwendet. Hier ist ein anderer Teil aus dem Rashumon Quellcode, in dem die Tastenbelegungen definiert werden:

/* HEBREW AND ENGLISH MAPS */
unsigned char regmap[] =
       ";1234567890-=\\ 0/'-˜€ˆ..."[] 123(tm)ƒ‚‹'‰‡ŒŠ",  456 †'„Ž-š•. .789 ";

unsigned char engmap[] =
       "`1234567890-=\\ 0qwertyuiop[] 123asdfghjkl;'  456 zxcvbnm,./ .789 ";

unsigned char shiftmap[] =
       "~!@#$%^&*()_+| 0QWERTYUIOP{} 123ASDFGHJKL:\"  456 ZXCVBNM<>? .789 ";

unsigned char shiftrus[] =
       "~!@#$%^&*()_+| 0°¶±³¸´¨(r)¯{} 123 ²£¥¦§(c)׫:\"  456 ¹·¢µ¡­¬<>? .789 ";

unsigned char rusmap[] =
       "`1234567890-=\\ 0׀ײִׁ׃״װָ־ֿ[] 123ְֳֵֶַֹֺֻׂ;'  456 ׳ֲױֱּֽ,./ .789 ";



Wie Sie sehen können, ist "regmap" die hebräische Codierung, "engmap" ist für lateinischen Text, "shiftmap" für die mittels SHIFT-Taste geschriebenen Zeichen und es gab auch eine Tastaturbelegung für Russisch (und später auch eine für Arabisch dank John Hajjer aus Chicago, der eine Menge Zeit darauf verwendete, um mir bei der Herausgabe einer arabischen Version zu helfen).
Das Umschalten zwischen den beiden Schreibrichtungen wurde mit einem einzigartigen Lineal mit zwei Versionen durchgeführt: links nach rechts  und rechts nach links:


Drücken den Pfeils wechselte die Schreibrichtung.

Das Scrollen von Text

Sogar offensichtliche Dinge, wie das Scrollen mussten damals erfunden werden. Dies beinhaltet die Bestimmung, wie viele Zeilen Text darzustellen sind, basierend auf der Fenstergröße (Amiga Fenster hatten die Fähigkeit, vom Endbenutzer in der Größe verändert sowie maximiert und minimiert zu werden), Darstellung eines Scrollbalkens und Berechnung der Scrollbarteilung, welche proportional zur möglichen Bewegung und dem verfügbaren Raum sein sollte.

scroll(ln,lines)
struct Line *ln;
intlines;
{
       registerSHORT distance,
                     top=TOP,
                     bot=BOT;
#ifDEBUG
       printf("BEFORE: top=%ld (%ld <> TOP=%ld) ",
                     Header->top->num,
                     Header->top->y,TOP+Header->shift);
       printf("bottom=%ld (%ld <> BOT=%ld)\n",
                     Header->bottom->num,
                     Header->bottom->y+LH(Header->bottom),BOT+Header->shift);
#endif
       if(lines>0)
       {
              distance=Header->bottom->next->y+LH(Header->bottom->next)-Header->shift-Header->Height;
              Header->shift+=distance;
              while(Header->top->y<Header->shift)
                     Header->top=Header->top->next;
              Header->bottom=Header->bottom->next;
       }
       else
       {
              distance=-(Header->shift-Header->top->prev->y);
              Header->shift+=distance;
              Header->top=Header->top->prev;
              while(Header->bottom->y+LH(Header->bottom)>Header->Height+Header->shift)
                     Header->bottom=Header->bottom->prev;
       }
       if(distance<100)
              ScrollRaster(rp,0,distance,0,TOP,640,BOT);
       else
              calc_top_bottom(TRUE,0,0);
#ifDEBUG
       printf("AFTER: top=%ld (%ld <> TOP=%ld) ",
                     Header->top->num,
                     Header->top->y,TOP+Header->shift);
       printf("bottom=%ld (%ld <> BOT=%ld)\n",
                     Header->bottom->num,
                     Header->bottom->y+LH(Header->bottom),BOT+Header->shift);
#endif
}


Zeilenumbruch von bidirektionalem Text

Aber nun lassen Sie uns zurückkommen auf den Zeilenumbruch von bidirektionalem Text. Im Grunde basierte der von mir zusammen mit Tamer Even-Zohar und ihrem Ehemann Nimrod entwickelte Algorithmus auf der Überprüfung einer gegebenen Zeile und falls diese länger als der Platz zwischen den beiden Spalten ist (Berechnung der Zeilenlänge in Pixeln unter Berücksichtigung jedes Zeichens basierend auf dessen unabhängige Attribute), müssten wir das letzte Wort daraus entfernen und dann erneut die Länge prüfen und so weiter, bis die Zeile innerhalb der Breite der Spalten passt. Die erste zu stellende Frage ist: Wo ist das "letzte" Wort? Wenn es ein linksläufiger Absatz ist, wird das letzte Word als erstes im Buffer erscheinen. In einem solchen Fall verwendete ich die folgende Funktion, welche in der Tat die Größe (in Pixel) es ersten Wortes in einem vorgegebenen Buffer maß. Die folgenden Routinen basieren auf unproportionalem Font, was kompliziert genug ist...

/* returns the len of the first word in s */
#define BLNK(c)      ((c)==' ' || (c)=='\n')
first_wordlen(s,margin,blnks1,blnks2)
char*s;
intmargin, *blnks1, *blnks2;
{
  registerint i, j;
/*     for (i=strlen(s)-1; BLNK(s[i]) && i; i--);
       if ((strlen(s)-(i+1))>1)  s[i+2] = '\0'; */
       for(i=margin; BLNK(s[i]) && s[i]; i++);
       *blnks1 = i;
       for(; !(BLNK(s[i])) && s[i]; i++);
       for(j=i; BLNK(s[j]) && s[i]; j++);
       *blnks2 = j-i;
       return(i);
}


Falls die Zeile rechtsläufig war, wurde eine andere Funktion verwendet:

last_wordlen(s,blnks1,blnks2,maxlen)
char*s;
int*blnks1, *blnks2, maxlen;
{
  registerint i, j;
       if(!strlen(s)) return(0);
       for(i=strlen(s)-1; BLNK(s[i]) && i; i--);
       if(i==0) return(0);
       *blnks1 = (strlen(s)-(i+1));
       for(i=min(maxlen,strlen(s)-1); BLNK(s[i]) && i; i--);
       for(; !(BLNK(s[i])) && i; i--);
       for(j=i; BLNK(s[j]) && j; j--);
       i++;
       *blnks2 = i - j;
       return(strlen(s) - i);
}


Natürlich entfernen wir nicht nur das letzte Word aus einer Zeile, sondern platzieren das erste Wort der nächsten Zeile zurück, wenn dort Platz verfügbar ist (zum Beispiel, wenn das erste Wort in der aktuellen Zeile gelöscht wird und Platz frei wird), also würde ein weiterer Baustein das nächste Wort (vom Beginn der nächsten Zeile) zurück zum Ende der aktuellen Zeile platzieren.

/* copies first word of length len & trailing blanks blnks fron s2 to s1 */
copy_first(s1,s2,len,blnks)
char*s1,*s2;
intlen,blnks;
{
       append(s2,s1,strlen(s1)+len+(blnks ? 1 : 0));
       delete1(s2,0,len+(blnks ? 1 : 0));
}


In Rashumon wurde die Schreibrichtung eines Textabsatzes automatisch berechnet, indem die Codierung aller Zeichen in jeder Zeile untersucht und besimmt wurde, welche Richtung vorherrschend ist. Bei den Überlegungen mit Tamar Even Zohar und ihrem Ehemann Nimrod, kamen wir zu der Einsicht, dass sogar das Leerzeichen " " eine Schreibrichtung haben kann und wir mussten entscheiden, ob wir ein hebräisches Leerzeichen zusätzlich zu dem lateinsichen haben wollten. Nun, diese Anforderung wurde ein "Muss", da es für den Zeilenumbruch von Absätzen mit der Kombination mehrerer Sprachen gebraucht wurde. Zum Beispiel:

"Dies ist ein Beispiel für einen Absatz gegenläufigen Sprachen.  זו דוגמה לפסקה עם שילוב של שתי שפות עם כיוונים מנוגדים" 

Der folgende Clip demonstriert, wie bidirektionaler Text von Rashumon editiert wird.

Nun, wenn Sie die Ränder verändern, welches Wort wird in die nächste Zeile "springen" oder in die aktuelle Zeile zurück "springen"? Der einzige Weg dies zu bestimmen ist, zu wissen, welche Richtung jedes Zeichen hat (entweder rechts nach links oder links nach rechts), einschließlich der Sonderzeichen wie Tabulatoren, Leerzeichen, Kommas etc. Rashumon kann immer noch bei Aminet unter diesem Link heruntergeladen werden.
An Article about Rashumon (UK)

Literaturhinweise

Mein Blog (Hebräisch)
Mein Blog (Englisch)