Simon: RTF Datei utf-8 codiert...

Hallo zusammen,

ich habe eine *.rtf Vorlage in welcher Platzhalter definiert sind, wie zB. %%DATUM%%. Diese Vorlage lese ich ein und tausche die Platzhalter gegen ein paar Variablen aus. Anschließend gebe ich die Datei direkt an den Browser (download) oder zu einem Script das die Datei per E-Mail verschickt.

Das funktioniert alles auch wunderbar.
Ich habe nun die Seite auf utf-8 Codierung umgestellt und habe das Problem das in der Rich Text Datei Umlaute (wie z.B. äöü) nicht sauber dargestellt werden. Jedoch nur die Umlaute, normaler Text geht hingegen... Das gleiche Ergebnis habe ich unabhängig ob ich die Datei an den Browser gebe oder per E-Mail sende.
Beispiel: http://www.test.weltreporter.net/test/Bild.png

  
  // ******************************  
  // RTF Vorlage laden, Text einfuegen und Senden  
  $rtfVorlage = fread(fopen($vorlage, "r"), filesize($vorlage));  
  
  
  // ******************************  
  // Ersetzungen vornehmen  
  $rtfVorlage = str_replace("%%DATUM%%", $datum, $rtfVorlage);  
  $rtfVorlage = str_replace("%%TITEL%%", $titel, $rtfVorlage);  
  $rtfVorlage = str_replace("%%BEMERKUNGEN%%", $bemerkungen, $rtfVorlage);  
  // Habe die Liste mal gekürzt, da sie unwichtig ist....  
  
  switch ($ausgabe) {  
    case 'browser':  
        $dateiName = gibDateinamen();  
  
        header("Cache-control: private");  
        header("Content-Type: application/rtf");  
        header("Content-Disposition: attachment; filename=".$dateiName);  
        print $rtfVorlage;  
  
        return 0;  
        break;  
  
    case 'email':  
        return $rtfVorlage;  
        break;  
  }  

Und hier noch eine Demo RTF Vorlage:

  
{\rtf1\mac\ansicpg10000\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1031\deflangfe1031{\upr{\fonttbl{\f0\fnil\fcharset256\fprq2{\*\panose 00020206030504050203}Times New Roman;}  
{\f1\fnil\fcharset256\fprq2{\*\panose 00020b06040202020202}Arial;}}{\*\ud{\fonttbl{\f0\fnil\fcharset256\fprq2{\*\panose 00020206030504050203}Times New Roman;}{\f1\fnil\fcharset256\fprq2{\*\panose 00020b06040202020202}Arial;}}}}  
{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;  
\red128\green0\blue128;\red128\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\nowidctlpar\aspalpha\faauto\rin0\lin0\itap0 \lang1031\langfe1031\cgrid\langnp1031\langfenp1031  
\snext0 \styrsid11221937 Normal;}{\*\cs10 \additive Default Paragraph Font;}{\*  
\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv  
\ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 Normal Table;}}{\*\rsidtbl \rsid11221937}{\info{\creatim\yr2008\mo3\dy1\hr9\min30}{\revtim\yr2008\mo3\dy1\hr9\min31}  
{\version1}{\edmins0}{\nofpages1}{\nofwords0}{\nofchars0}{\nofcharsws0}{\vern24577}}\paperw11900\paperh16840\margl1417\margr1417\margt1417\margb1134  
\deftab708\ftnbj\aenddoc\hyphhotz425\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul\formshade\horzdoc\dghspace180\dgvspace180\dghorigin1701\dgvorigin1984\dghshow0\dgvshow0  
\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\splytwnine\ftnlytwnine\htmautsp\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr\lnbrkrule\nobrkwrptbl\rsidroot16064709 \fet0\sectd  
\linex0\headery708\footery708\colsx708\endnhere\sectdefaultcl\sectrsid10818643\sftnbj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang{\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang  
{\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang{\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl7  
\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang{\pntxtb (}{\pntxta )}}\pard\plain  
\ql \li0\ri0\nowidctlpar\aspalpha\faauto\rin0\lin0\itap0 \lang1031\langfe1031\cgrid\langnp1031\langfenp1031 {\v\f1\fs18\insrsid11221937  
\par %%DATUM%%  
\par }{\b\v\f1\fs28\insrsid11221937 %%TITEL%%  
\par }{\v\f1\insrsid11221937  
\par  
\par  
\par }{\v\f1\fs18\insrsid11221937 Bemerkung:  
\par %%BEMERKUNGEN%%  
\par }{\insrsid16064709  
\par }}  

Ich möchte also gerne in der Datei die Umlaute (Sonderzeichen) richtig dargestellt bekommen. Eine Überlegung (die auch teilw. funktioniert) ist die Strings mit mb_convert_encoding() in eine andere Codierung (zB ISO-8859-15) zu wandeln. Das geht aber nur solange die Zeichen auch in ISO-8859-15 enthalten sind, was wegen UTF-8 nicht bei allen Zeichen zutrifft.

Kann mir jemand einen Tipp geben wir ich das Problem lösen kann?
Wie kann ich IN einer Rich Text Datei die Codierung angeben?

Vielen Dank

  • Simon
  1. echo $begrüßung;

    Ich habe nun die Seite auf utf-8 Codierung umgestellt und habe das Problem das in der Rich Text Datei Umlaute (wie z.B. äöü) nicht sauber dargestellt werden.

    Dann hast du eine Diskrepanz zwischen der verwendeten Zeichenkodierung einerseits und der angegebenen oder vom Empfänger per Defaultwert angenommenen andererseits. Beseitige diese Diskrepanz.

    Kann mir jemand einen Tipp geben wir ich das Problem lösen kann?

    Den hab ich doch schon in diesem Thread gegeben: https://forum.selfhtml.org/?t=167300&m=1091038

    Wie kann ich IN einer Rich Text Datei die Codierung angeben?

    Soweit ich weiß ist das mit einer Angabe am Anfang der RTF-Datei zu lösen. Diese Angabe ist in der RTF-Spezifikation zu finden.

    Wo ist dein Problem? Kannst du die Spezifikation nicht deuten und entsprechend umsetzen? Versuch doch mal mit Word oder einem anderen RTF-fähigen Editor einen Text mit Zeichen innerhalb und außerhalb von Windows-1252 zu erstellen, und schau dir an, was der beim Speichern an den Anfang setzt.

    echo "$verabschiedung $name";

    1. Hallo dedlfix,

      Wie kann ich IN einer Rich Text Datei die Codierung angeben?

      Soweit ich weiß ist das mit einer Angabe am Anfang der RTF-Datei zu lösen. Diese Angabe ist in der RTF-Spezifikation zu finden.

      Wo ist dein Problem? Kannst du die Spezifikation nicht deuten und entsprechend umsetzen? Versuch doch mal mit Word oder einem anderen RTF-fähigen Editor einen Text mit Zeichen innerhalb und außerhalb von Windows-1252 zu erstellen, und schau dir an, was der beim Speichern an den Anfang setzt.

      Genau das habe ich versucht. Doch leider steht dort nur folgendes:

      {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf440  
      {\fonttbl\f0\fswiss\fcharset77 Helvetica;}  
      {\colortbl;\red255\green255\blue255;}  
      \paperw11900\paperh16840\margl1440\margr1440\vieww9000\viewh8400\viewkind0  
      \pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\ql\qnatural\pardirnatural  
        
      \f0\fs24 \cf0 ein ae: \'8a\  
      ein oe: \'9a\  
      ein ue: \'9f\  
      und ein ss: \'a7}
      

      Sprich, aus "ä" wird "'8a". Am Anfang der Datei finde ich nicht wirklich einen Hinweis auf die Codierung. Der Links den du gepostet hattest (Spezifizierung) hat mich leider auch nicht weitergebracht. Konnte da ebenfalls nichts finden...

      Habe auch versucht rauszufinden was '8a genau für eine Codierung ist, aber leider ebenfalls ohne Erfolg. Sonst könnte ich ja selbst die Zeichen alle umwandeln...

      Ich bekomm es einfach nciht hin!

      Gruss

      • Simon
      1. Am Anfang der Datei finde ich nicht wirklich einen Hinweis auf die Codierung.

        Doch, da:

        {\rtf1\mac\ansicpg10000\cocoartf824\cocoasubrtf440

        ---------^^^^

        ein ae: '8a\

        Sprich, aus "ä" wird "'8a".

        Habe auch versucht rauszufinden was '8a genau für eine Codierung ist, aber leider ebenfalls ohne Erfolg.

        Ich rate jetzt einfach mal, dass Du an Position 0x8a bzw. 138 (dezimal) in einem wie auch immer gearteten Mac-Zeichensatz (hat bestimmt auch einen richtigen Namen) genauso wie vermutlich in ISO-8859-1 das ä finden wirst.

  2. Ich habe nun die Seite auf utf-8-Codierung umgestellt und habe das Problem das in der Rich-Text-Datei Umlaute (wie z.B. äöü) nicht sauber dargestellt werden.

    Schau doch nochmal in die Microsoft-Doku, taugt sicher nicht zum Supersonderschnellüberblick, aber ich finde sie recht leicht verständlich. Wichtig für dich ist Seite 13, dort findet sich auch ein klares Beispiel:

    For example, the text LabΓValue (Unicode characters 0x004c, 0x0061, 0x0062, 0x0393, 0x0056, 0x0061, 0x006c, 0x0075, 0x0065) should be represented as follows (assuming a previous \ucl): Lab\u915GValue

    D.h. der griechische Buchstabe Γ, Unicode-Position 915 (dezimal) bzw. 0x393 (hex) wird als \u915G notiert, also \u gefolgt vom gewünschten Dezimalwert.
    Das G, das darauf folgt, ist ein Ersatzzeichen; es wird genutzt, wenn der Computer mit dem vorangehenden Unicode-Wert nichts anfangen kann. Der angesprochene Steuercode \uc1 besagt, wieviele Bytes als Ersatz vorgesehen sind, \uc1 wäre also ein Zeichen. Man könnte aber genauso gut \uc5Lab\u915GammaValue schreiben, das würde LabΓValue oder als Unicode-Ersatz LabGammaValue werden.

    \uc1 ist in deiner Vorlage schon eingebaut, und zwar ganz am Anfang, als vierter Steuercode:

    {\rtf1\mac\ansicpg10000\uc1

    Du kannst \uc1 auch auf \uc0 setzen und dir die Ersatzzeichen sparen. Ich denke, das ist gerade bei universellen Vorlagen einfacher und stiftet heutzutage auch keine Verwirrung mehr.

    PS: Kauf dich mal ein paar Bindestriche ;->

    1. Hallo Gonzo,

      vielen Dank für deine ausführlichen Antworten! Soweit habe ich das verstanden. Ich habe mit der Funktion ord() versucht die einzelnen Zeichen des Strings in die dezimal-Werte umzuwandeln. Das funktioniert nur leider nicht mit den Umlauten. Für "ä" bekomme ich anstatt 228 195 raus. Gleiches Problem mit öü und ß.

      Kann PHP mit UTF-8 Strings umgehen? Wie kann ich ansonsten den dezimal-Wert ermitteln? Hätte nie gedacht das ich solche Probleme mit RTF bekomme... :(

      Danke noch mal...

      Gruss

      • Simon
      1. echo $begrüßung;

        Ich habe mit der Funktion ord() versucht die einzelnen Zeichen des Strings in die dezimal-Werte umzuwandeln. Das funktioniert nur leider nicht mit den Umlauten. Für "ä" bekomme ich anstatt 228 195 raus. Gleiches Problem mit öü und ß.

        ord() arbeitet byteweise. Das nützt die bei UTF-8-Kodierung herzlich wenig. Eher ist da noch ISO-8859-1 zielführend, weil dessen Bytewerte den Unicode-Codepoints entsprechen. Allerdings bist du damit auf die 256 ISO-8859-1-Zeichen eingeschränkt.

        Kann PHP mit UTF-8 Strings umgehen?

        Jein, nicht wirklich. Es gibt einige Funktionen, die mit UTF-8 umgehen können, meist Konvertierfunktionen, aber im Allgemeinen wird erst PHP6 vollständig fähig sein, mit Mehrbyte-Kodierungen richtig umzugehen.

        Wie kann ich ansonsten den dezimal-Wert ermitteln?

        Du musst den Unicode-Codepoint kennen. Den kannst du aus der UTF-8-Bytesequenz zurückrechnen oder mit iconv ermitteln. Das kennt auch Unicode. Leider ist das nicht überall verfügbar.

        Hätte nie gedacht das ich solche Probleme mit RTF bekomme... :(

        RTF ist ein recht altes Format, und so wie es aussieht auf 7 Bit ausgelegt. Deswegen macht es wohl auch solche Umstände bei Unicode-Zeichen. Hast du schon mal gesucht, ob es da was für PHP gibt, das mit dieses Dateiformat und seinen Besonderheiten umzugehen vermag?

        echo "$verabschiedung $name";

        1. Ich habe mit der Funktion ord() versucht die einzelnen Zeichen des Strings in die dezimal-Werte umzuwandeln. Das funktioniert nur leider nicht mit den Umlauten. Für "ä" bekomme ich anstatt 228 195 raus. Gleiches Problem mit öü und ß.

          Wie kann ich ansonsten den dezimal-Wert ermitteln?

          Du musst den Unicode-Codepoint kennen. Den kannst du aus der UTF-8-Bytesequenz zurückrechnen oder mit iconv ermitteln. Das kennt auch Unicode. Leider ist das nicht überall verfügbar.

          Ich habe mal spaßeshalber eine Dekodierroutine gebastelt, die ohne externe Hilfen auskommt. So ganz trivial, wie ich dachte, war das mitsamt Fehlerprüfungen dann doch nicht …

            
          function utf8rtf($eingabe) {  
            
              //  
              // Parameter zum Erkennen und Prüfen von utf-8-Bytesequenzen  
              //   sequenz:    Anzahl der von dieser Sequenz belegten Bytes.  
              //   startmaske: Bitmaske, um Startbyte zu erkennen bzw. invertiert, um Nutzbits aus dem Startbyte zu filtern.  
              //   startcode:  Filterung des Startbytes mit startmaske muss diesen Wert ergeben.  
              //   min:        Diese Sequenz muss mindestens den Wert min beherbergen, andernfalls hätte eine kürzere Sequenz zu benutzt werden müssen.  
              $utf = Array();  
              // $utf[] = Array("sequenz" => "1", "startmaske" => 128, "startcode" => 0, "min" => 0); - ein Byte lässt sich gesondert schneller behandeln  
              $utf[] = Array("sequenz" => "2", "startmaske" => 224, "startcode" => 192, "min" => 128);  
              $utf[] = Array("sequenz" => "3", "startmaske" => 240, "startcode" => 224, "min" => 2048);  
              $utf[] = Array("sequenz" => "4", "startmaske" => 248, "startcode" => 240, "min" => 65536);  
              // Ein mit utf-8 kodierter Wert kann theoretisch mehr als vier Bytes belegen, tut es in der Unicode-Praxis aber nie.  
            
              //  
              // Weitere Variablen  
              $ausgabe = "{\uc0"; // Erhält Ergebnis der Konvertierung. RTF-utf-8-Steuercodes folgen in diesem RTF-Block ({) keine Ersatzbytes (\uc0).  
              $laenge = strlen($eingabe);  
            
              //  
              // Die große Rundfahrt.  
              for ($e = 0; $e < $laenge; $e++) {  
            
                  $x = false; // dekodierte Unicode-Nummer des Zeichens, false = ungültig  
                  $c = ord($eingabe{$e}); // Wert des aktuellen Bytes  
            
                  if ($c < 128) { // US-ASCII-Zeichen schnell und schmerzlos 1:1 übernehmen  
                      $x = $c;  
                  }  
                  else if ($c >= 192) { // utf-8-Startbyte  
                      //  
                      // utf-8-Sequenz erkennen  
                      foreach ($utf as $u) {  
                          if (($c & $u["startmaske"]) == $u["startcode"]) { // Bytewert maskieren und mit Sequenzstartcode vergleichen  
                              $x = $c & (~ $u["startmaske"]); // aus dem Bytewert die Nutzbits herausmaskieren, dazu dient die invertierte Startmaske  
                              break; // Sequenz gefunden, weiter geht's unten ...  
                          }  
                      }  
                      $e++; // nächste Position in der Eingabezeichenkette  
            
                      //  
                      // Folgebytes einlesen und zu $x hinzurechnen  
                      $i = 0;  
                      while (($e + $i < $laenge) && ((($c = ord($eingabe{$e + $i})) & 192) == 128)) { // utf-8-Folgebytes: [Byte] & 1100 0000 (192) muss 1000 0000 (128) sein, sonst gehört's nicht zur Sequenz.  
                          if (($x !== false) && ($i < $u["sequenz"] - 1)) { // gültige utf-8-Sequenz erkannt und dieses Folgebyte wird noch erwartet  
                              $x <<= 6;                 // vorhandene Bits um sechs Stellen nach links schieben und  
                              $x += $c & 63;            // neue sechs Bits in freien Platz einfügen  
                          }  
                          $i++;  
                      }  
            
                      //  
                      // Gelesenen Unicode-Wert prüfen  
                      if (($x !== false) || ($i != $u["sequenz"] - 1) || ($x < $u["min"])) { // Fehlerhafte utf-8-Bytefolge: Keine Sequenz oder zu lang bzw. zu kurz oder einen Wert in einer zu großen Sequenz geparkt.  
                          $x = false;  
                      }  
            
                      //  
                      // Schon mal an nächste Position in der Eingabezeichenkette springen.  
                      $e += $i - 1;  
                  }  
            
                  //  
                  // Ungültige Unicode-Werte. Es gibt weitere, die ich jetzt aber still und heimlich unterschlage ...  
                  if (($x == 65534) || ($x == 65535)) {  
                      $x = false;  
                  }  
            
                  //  
                  // Unicode-Wert RTF-kompatibel machen  
                  if ($x > 65535) { // RTF bzw. Word kann nur 16-Bit-Werte verarbeiten.  
                      $x = false;  
                  }  
                  else if ($x > 32767) { // RTF erwartet vorzeichenbehaftete 16-Bit-Werte, d.h. im Bereich von -32768 bis +32767.  
                      $x = 32767 - $x;  
                  }  
            
                  //  
                  // Erkannten Unicode-Wert oder Fehlerplatzhalter ? ausgeben.  
                  if ($x === false) { // Kein gültiger Unicode-Wert.  
                      $ausgabe .= "?";  
                  }  
                  else if (($x < 128) && ($x >= 0)) { // US-ASCII unverändert ausgeben. Wegen RTF kann x auch kleiner als 0 sein.  
                      $ausgabe .= chr($x);  
                  }  
                  else { // Alle anderen Zeichen gemäß RTF maskieren.  
                      $ausgabe .= sprintf('\u%d ', $x); // Leerzeichen trennt RTF-Steuercode zum nächsten Textzeichen ab, ansonsten würde eine nachfolgende Zahl zum \u-Steuercode hinzugezählt werden.  
                  }  
            
              }  
            
              $ausgabe .= "}"; // Eingangs mit {\uc0 begonnenen RTF-Block wieder  
              return $ausgabe;  
          }  
          
          
          1. Hi Gonzo,

            Ich habe mal spaßeshalber eine Dekodierroutine gebastelt, die ohne externe Hilfen auskommt. So ganz trivial, wie ich dachte, war das mitsamt Fehlerprüfungen dann doch nicht …

            WOW, nicht schlecht. Und schon mal besten Dank für das Angagement!
            Doch leider funktioniert die Funktion bei mir nicht...

            Folgendes habe ich getestet:

              
              
            // Ich habe den Text auch testweise aus einer DB geladen, jedoch mit dem gleichen Ergebnis.  
            $text = "Test von Simon äöüßµ \par ENDE";  
            print utf8rtf($text);
            

            Ausgabe: "{\uc0Test von Simon ????? \par ENDE}"

            Ich habe in die Fkt mal verschiedene Ausgaben eingebaut um zu prüfen wo $x = false gesetzt wird.
            Es scheint bei der Überprüfung zu passieren:

              
            // Gelesenen Unicode-Wert prüfen  
            if (($x !== false) || ($i != $u["sequenz"] - 1) || ($x < $u["min"])) { // Fehlerhafte utf-8-Bytefolge: Keine Sequenz oder zu lang bzw. zu kurz oder einen Wert in einer zu großen Sequenz geparkt.  
              $x = false;  
            }  
            
            

            Die Datei ist als "UTF-8, no BOM" abgespeichert, die Seite mit UTF-8 Codierung ausgegeben. Wenn ich $text einfach ausgebe, ist es auch lesbar...

            Hast du die Zeile
            //$utf[] = Array("sequenz" => "1", "startmaske" => 128, "startcode" => 0, "min" => 0); // - ein Byte lässt sich gesondert schneller behandeln
            absichtlich auskommentiert? Wenn ich sie nicht auskommentiere geht es jedoch auch nicht...

            Irgend eine Idee was ich anders mache als Du?

            Vielen Dank!

            • Simon
            1. Doch leider funktioniert die Funktion bei mir nicht...

              Da war ein Fehler drin, den ich verbockt habe, als ich den Code hier im Forumsformular nochmal verschlankt hatte:

              // Gelesenen Unicode-Wert prüfen
              if (($x !== false) || ($i != $u["sequenz"] - 1) || ($x < $u["min"])) {
                  $x = false;

              if (($x === false) || ($i != $u["sequenz"] - 1) || ($x < $u["min"])) {
                     $x = false;

              Die erste $x-Prüfung muss === sein, nicht !==.

              Falls es dir etwas merkwürdig vorkommt, dass ich erst prüfe, ob x false ist, und falls ja, x auf false setze, obwohl x doch schon false ist: Die x-Prüfung steht da, weil x gleichzeitig anzeigt, ob in u gültige utf-8-Sequenzdaten drinstehen. Nur, wenn x nicht false ist, hat die $utf-Schleife zuvor auch etwas Brauchbares in u hinterlassen.

              Hast du die Zeile
              //$utf[] = Array("sequenz" => "1", "startmaske" => 128, "startcode" => 0, "min" => 0); // - ein Byte lässt sich gesondert schneller behandeln
              absichtlich auskommentiert?

              Diese Zeile hatte ich nur drin, weil theoretisch auch Ein-Byte-Sequenzen mit der Schleife abgefragt werden können, ein reiner Hinweis, dass es auch ginge. Es ist jedoch schneller, wenn man einfach schaut, ob ein Byte kleiner als 128 ist, anstatt in der $utf-Schleife (($c & 128) == 0) zu prüfen.

              Irgend eine Idee was ich anders mache als Du?

              Ja, du hast den Kram ausprobiert :-]

              1. Hallo Gonzo,

                Geil! Das funktioniert echt gut. Hab es sogar erfolgreich mit Chinesisch getestet ;)

                $ausgabe = "{\uc0"; und  
                $ausgabe .= "}";
                

                auskommentiert, damit ich meine RTF-Vorlage direkt komplett übergeben kann an die Fkt.

                $ausgabe .= sprintf('\u%d ', $x); geändert in $ausgabe .= sprintf('\u%d?', $x);, da mit dem Leerzeichen hinter "%d" teilweise Zeichen "verschluckt" wurden. So geht es aber nun!

                Du solltest die Methode irgendwo veröffentlichen, da ich soetwas bisher nicht gefunden habe und bestimmt vielen helfen kann!

                Nochmal besten Dank und lass mich wissen, wenn ich mich revangieren kann!

                Gruss

                • Simon