2
0
Эх сурвалжийг харах

o patch by Nikolay Nikolov to make the text mode IDE look pretty under
modern Linuxes by a patch for UTF-8 console output.
Previously, only BeOS used UTF-8. Tested with:
- the linux console
- xterm
- gnome-terminal
- konsole
- rxvt-unicode
using Fedora 11.
Tested with
- gnome-terminal
- xterm
- konsole
using Ubuntu 9.04
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.

git-svn-id: trunk@13651 -

florian 16 жил өмнө
parent
commit
a023c165da
2 өөрчлөгдсөн 76 нэмэгдсэн , 27 устгасан
  1. 3 2
      rtl/unix/convert.inc
  2. 73 25
      rtl/unix/video.pp

+ 3 - 2
rtl/unix/convert.inc

@@ -47,12 +47,13 @@ const convert_linuxlowascii_to_vga:array[#0..#31] of word=(
         $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 }

+ 73 - 25
rtl/unix/video.pp

@@ -41,7 +41,8 @@ type  Tencoding=(cp437,         {Codepage 437}
                  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 @@ const
   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 @@ begin
   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 @@ begin
     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 @@ var
         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 @@ begin
   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 @@ begin
       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 @@ begin
          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 @@ begin
      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 @@ begin
      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_strings=@term_codes_xterm then
+    begin
+      TerminalSupportsBold := false;
+      TerminalSupportsHighIntensityColors := true;
+    end
+    else
+    begin
+      TerminalSupportsBold := true;
+      TerminalSupportsHighIntensityColors := false;
+    end;
     if cur_term_strings=@term_codes_freebsd then
       console:=ttyFreeBSD;
 {$ifdef linux}
@@ -1090,16 +1132,22 @@ begin
 {$endif}
         if cur_term_strings=@term_codes_linux then
           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}