Hi all,

spent some time today, trying to make the text mode IDE look pretty under modern Linuxes and here's the result - a patch for UTF-8 console output. Previously, only BeOS used UTF-8. Tested with:

- the linux console
- xterm
- gnome-terminal
- konsole
- rxvt-unicode

all under Fedora 11. Known "features":

- high intensity colours were actually normal intensity, with a bold attribute set. This worked fine under gnome-terminal, but xterm didn't have bold versions of all cp437 characters, which screwed up the window borders in the IDE. And although konsole had them, I didn't like the font - it converted all the double window borders to a very thick single-line border. So I disabled the bolding of high intensity colours in all X11 terminals (TERM=xterm) and replaced it with another ANSI attribute, that actually sets high intensity colours, but is not (in theory) supported by all terminals. The linux console doesn't support it - it actually wants a bold attribute, to set high intensity, so that's why I enabled it only for X11 terminals. All the ones, that I tried, worked fine (xterm, gnome-terminal, konsole, rxvt-unicode, also the plain old rxvt, with a non-UTF-8 locale). - Fedora 11 by default uses a 512-characters font, called latarcyrheb-sun16 for the linux text mode console, which disables the high intensity colours, effectively reducing the set of available colours to only 8. This is a hardware limitation of the VGA hardware and can be avoided by using a 256-character font. It does not need to be cp437, but it has to have an unicode mapping. - I haven't tried other linux distros (and unix-like OSes, i.e. FreeBSD and Mac OS X) - although they should work in theory, they might look bad, due to different fonts, etc.
Index: rtl/unix/video.pp
===================================================================
--- rtl/unix/video.pp	(revision 13607)
+++ rtl/unix/video.pp	(working copy)
@@ -41,7 +41,8 @@
                  iso10,         {ISO 8859-10}
                  iso13,         {ISO 8859-13}
                  iso14,         {ISO 8859-14}
-                 iso15);        {ISO 8859-15}
+                 iso15,         {ISO 8859-15}
+                 utf8);         {UTF-8}
 
 const  {Contains all code pages that can be considered a normal vga font.
         Note: KOI8-R has line drawing characters in wrong place. Support
@@ -245,6 +246,9 @@
   ACSOut : string = '';
   in_ACS : boolean =false;
 
+  TerminalSupportsHighIntensityColors: boolean = false;
+  TerminalSupportsBold: boolean = true;
+
 function convert_vga_to_acs(ch:char):word;
 
 {Ch contains a character in the VGA character set (i.e. codepage 437).
@@ -453,16 +457,17 @@
   OFg:=OAttr and $f;
   OBg:=OAttr shr 4;
   attr2ansi:=#27'[';
-  if fg and 8<>0 then
-    begin
-      {Enable bold if not yet on.}
-      if ofg and 8=0 then
-        attr2ansi:=attr2ansi+'1;';
-    end
-  else
-    {Disable bold if on.}
-    if ofg and 8<>0 then
-      attr2ansi:=attr2ansi+'22;';
+  if TerminalSupportsBold then
+    if fg and 8<>0 then
+      begin
+        {Enable bold if not yet on.}
+        if ofg and 8=0 then
+          attr2ansi:=attr2ansi+'1;';
+      end
+    else
+      {Disable bold if on.}
+      if ofg and 8<>0 then
+        attr2ansi:=attr2ansi+'22;';
   if bg and 8<>0 then
     begin
       {Enable bold if not yet on.}
@@ -474,8 +479,19 @@
     if obg and 8<>0 then
       attr2ansi:=attr2ansi+'25;';
 
-  if fg and 7<>ofg and 7 then
-     attr2ansi:=attr2ansi+'3'+ansitbl[fg and 7]+';';
+  if TerminalSupportsHighIntensityColors then
+  begin
+    if fg and 15<>ofg and 15 then
+      if fg and 8<>0 then
+        attr2ansi:=attr2ansi+'9'+ansitbl[fg and 7]+';'
+      else
+        attr2ansi:=attr2ansi+'3'+ansitbl[fg and 7]+';';
+  end
+  else
+  begin
+    if fg and 7<>ofg and 7 then
+      attr2ansi:=attr2ansi+'3'+ansitbl[fg and 7]+';';
+  end;
   if bg and 7<>obg and 7 then
      attr2ansi:=attr2ansi+'4'+ansitbl[bg and 7]+';';
 
@@ -624,7 +640,7 @@
         case c of
           #0..#31:
             converted:=convert_lowascii_to_UTF8[c];
-          #128..#255:
+          #127..#255:
             converted:=convert_cp437_to_UTF8[c];
           else
           begin
@@ -942,6 +958,18 @@
   TCSetAttr(1,TCSANOW,tio);
 end;
 
+function UTF8Enabled: Boolean;
+var
+  lang:string;
+begin
+  {$ifdef BEOS}
+  UTF8Enabled := true;
+  exit;
+  {$endif}
+  lang:=upcase(fpgetenv('LANG'));
+  UTF8Enabled := (Pos('.UTF-8', lang) > 0) or (Pos('.UTF8', lang) > 0);
+end;
+
 procedure decide_codepages;
 
 var s:string;
@@ -970,6 +998,11 @@
       internal_codepage:=cp852;
     iso05:               {Cyrillic}
       internal_codepage:=cp866;
+    utf8:
+      begin
+        internal_codepage:=cp437;
+        convert:=cv_cp437_to_UTF8;
+      end;
     else
       if internal_codepage in vga_codepages then
         internal_codepage:=external_codepage
@@ -978,9 +1011,6 @@
          437 in the hope that the actual font has similarity to codepage 437.}
         internal_codepage:=cp437;
   end;
-  {$ifdef BEOS}
-  convert := cv_cp437_to_UTF8;  
-  {$endif}
 end;
 
 
@@ -1045,6 +1075,8 @@
      Console:=TTyNetwork;                 {Default: Network or other vtxxx tty}
      cur_term_strings:=...@term_codes_vt100; {Default: vt100}
      external_codepage:=iso01;            {Default: ISO-8859-1}
+     if UTF8Enabled then
+       external_codepage:=utf8;
    {$ifdef linux}
      if vcs_device>=0 then
        begin
@@ -1082,6 +1114,16 @@
      for i:=low(terminal_names) to high(terminal_names) do
        if copy(term,1,length(terminal_names[i]))=terminal_names[i] then
          cur_term_strings:=terminal_data[i];
+    if cur_term_strin...@term_codes_xterm then
+    begin
+      TerminalSupportsBold := false;
+      TerminalSupportsHighIntensityColors := true;
+    end
+    else
+    begin
+      TerminalSupportsBold := true;
+      TerminalSupportsHighIntensityColors := false;
+    end;
     if cur_term_strin...@term_codes_freebsd then
       console:=ttyFreeBSD;
 {$ifdef linux}
@@ -1092,14 +1134,22 @@
           begin
             {Executed in case ttylinux is false (i.e. no vcsa), but
              TERM=linux.}
-            {Enable the VGA character set (codepage 437,850,....)}
-            fpwrite(stdoutputhandle,font_vga,sizeof(font_vga));
-            external_codepage:=cp437;  {Now default to codepage 437.}
+            if external_codepage<>utf8 then
+              begin
+                {Enable the VGA character set (codepage 437,850,....)}
+                fpwrite(stdoutputhandle,font_vga,sizeof(font_vga));
+                external_codepage:=cp437;  {Now default to codepage 437.}
+              end;
           end
         else
-          {No VGA font :( }
-          fpwrite(stdoutputhandle,font_lat1,sizeof(font_lat1));
-        { running on a remote terminal, no error with /dev/vcsa }
+          begin
+            if external_codepage<>utf8 then
+            begin
+              {No VGA font :( }
+              fpwrite(stdoutputhandle,font_lat1,sizeof(font_lat1));
+            end;
+            { running on a remote terminal, no error with /dev/vcsa }
+          end;
    {$ifdef linux}
       end;
    {$endif}
Index: rtl/unix/convert.inc
===================================================================
--- rtl/unix/convert.inc	(revision 13607)
+++ rtl/unix/convert.inc	(working copy)
@@ -47,12 +47,13 @@
         $00b0,$00a8,$00b7,$00b9,$00b3,$00b2,$002a,$00a0  { $f8..$ff }
       );
       convert_lowascii_to_UTF8:array[#0..#31] of WideChar=(
-        #0000,#9786,#9787,#9829,#9830,#9827,#9824,#8226,
+        #8199,#9786,#9787,#9829,#9830,#9827,#9824,#8226,
         #9688,#9675,#9689,#9794,#9792,#9834,#9835,#9788,
         #9658,#9668,#8597,#8252,#0182,#0167,#9644,#8616,
         #8593,#8595,#8594,#8592,#8735,#8596,#9650,#9660
       );
-      convert_cp437_to_UTF8:array[#128..#255] of WideChar=(
+      convert_cp437_to_UTF8:array[#127..#255] of WideChar=(
+                                                  #8962, { $7f }
         #0199,#0252,#0233,#0226,#0228,#0224,#0229,#0231, { $80..$87 }
         #0234,#0235,#0232,#0239,#0238,#0236,#0196,#0197, { $88..$8f }
         #0201,#0230,#0198,#0244,#0246,#0242,#0251,#0249, { $90..$97 }
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to