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 -
This commit is contained in:
florian 2009-09-05 14:54:22 +00:00
parent eb84d329d4
commit a023c165da
2 changed files with 76 additions and 27 deletions

View File

@ -47,12 +47,13 @@ const convert_linuxlowascii_to_vga:array[#0..#31] of word=(
$00b0,$00a8,$00b7,$00b9,$00b3,$00b2,$002a,$00a0 { $f8..$ff } $00b0,$00a8,$00b7,$00b9,$00b3,$00b2,$002a,$00a0 { $f8..$ff }
); );
convert_lowascii_to_UTF8:array[#0..#31] of WideChar=( 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, #9688,#9675,#9689,#9794,#9792,#9834,#9835,#9788,
#9658,#9668,#8597,#8252,#0182,#0167,#9644,#8616, #9658,#9668,#8597,#8252,#0182,#0167,#9644,#8616,
#8593,#8595,#8594,#8592,#8735,#8596,#9650,#9660 #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 } #0199,#0252,#0233,#0226,#0228,#0224,#0229,#0231, { $80..$87 }
#0234,#0235,#0232,#0239,#0238,#0236,#0196,#0197, { $88..$8f } #0234,#0235,#0232,#0239,#0238,#0236,#0196,#0197, { $88..$8f }
#0201,#0230,#0198,#0244,#0246,#0242,#0251,#0249, { $90..$97 } #0201,#0230,#0198,#0244,#0246,#0242,#0251,#0249, { $90..$97 }

View File

@ -41,7 +41,8 @@ type Tencoding=(cp437, {Codepage 437}
iso10, {ISO 8859-10} iso10, {ISO 8859-10}
iso13, {ISO 8859-13} iso13, {ISO 8859-13}
iso14, {ISO 8859-14} 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. const {Contains all code pages that can be considered a normal vga font.
Note: KOI8-R has line drawing characters in wrong place. Support Note: KOI8-R has line drawing characters in wrong place. Support
@ -245,6 +246,9 @@ const
ACSOut : string = ''; ACSOut : string = '';
in_ACS : boolean =false; in_ACS : boolean =false;
TerminalSupportsHighIntensityColors: boolean = false;
TerminalSupportsBold: boolean = true;
function convert_vga_to_acs(ch:char):word; function convert_vga_to_acs(ch:char):word;
{Ch contains a character in the VGA character set (i.e. codepage 437). {Ch contains a character in the VGA character set (i.e. codepage 437).
@ -453,16 +457,17 @@ begin
OFg:=OAttr and $f; OFg:=OAttr and $f;
OBg:=OAttr shr 4; OBg:=OAttr shr 4;
attr2ansi:=#27'['; attr2ansi:=#27'[';
if fg and 8<>0 then if TerminalSupportsBold then
begin if fg and 8<>0 then
{Enable bold if not yet on.} begin
if ofg and 8=0 then {Enable bold if not yet on.}
attr2ansi:=attr2ansi+'1;'; if ofg and 8=0 then
end attr2ansi:=attr2ansi+'1;';
else end
{Disable bold if on.} else
if ofg and 8<>0 then {Disable bold if on.}
attr2ansi:=attr2ansi+'22;'; if ofg and 8<>0 then
attr2ansi:=attr2ansi+'22;';
if bg and 8<>0 then if bg and 8<>0 then
begin begin
{Enable bold if not yet on.} {Enable bold if not yet on.}
@ -474,8 +479,19 @@ begin
if obg and 8<>0 then if obg and 8<>0 then
attr2ansi:=attr2ansi+'25;'; attr2ansi:=attr2ansi+'25;';
if fg and 7<>ofg and 7 then if TerminalSupportsHighIntensityColors then
attr2ansi:=attr2ansi+'3'+ansitbl[fg and 7]+';'; 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 if bg and 7<>obg and 7 then
attr2ansi:=attr2ansi+'4'+ansitbl[bg and 7]+';'; attr2ansi:=attr2ansi+'4'+ansitbl[bg and 7]+';';
@ -624,7 +640,7 @@ var
case c of case c of
#0..#31: #0..#31:
converted:=convert_lowascii_to_UTF8[c]; converted:=convert_lowascii_to_UTF8[c];
#128..#255: #127..#255:
converted:=convert_cp437_to_UTF8[c]; converted:=convert_cp437_to_UTF8[c];
else else
begin begin
@ -942,6 +958,18 @@ begin
TCSetAttr(1,TCSANOW,tio); TCSetAttr(1,TCSANOW,tio);
end; 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; procedure decide_codepages;
var s:string; var s:string;
@ -970,6 +998,11 @@ begin
internal_codepage:=cp852; internal_codepage:=cp852;
iso05: {Cyrillic} iso05: {Cyrillic}
internal_codepage:=cp866; internal_codepage:=cp866;
utf8:
begin
internal_codepage:=cp437;
convert:=cv_cp437_to_UTF8;
end;
else else
if internal_codepage in vga_codepages then if internal_codepage in vga_codepages then
internal_codepage:=external_codepage internal_codepage:=external_codepage
@ -978,9 +1011,6 @@ begin
437 in the hope that the actual font has similarity to codepage 437.} 437 in the hope that the actual font has similarity to codepage 437.}
internal_codepage:=cp437; internal_codepage:=cp437;
end; end;
{$ifdef BEOS}
convert := cv_cp437_to_UTF8;
{$endif}
end; end;
@ -1045,6 +1075,8 @@ begin
Console:=TTyNetwork; {Default: Network or other vtxxx tty} Console:=TTyNetwork; {Default: Network or other vtxxx tty}
cur_term_strings:=@term_codes_vt100; {Default: vt100} cur_term_strings:=@term_codes_vt100; {Default: vt100}
external_codepage:=iso01; {Default: ISO-8859-1} external_codepage:=iso01; {Default: ISO-8859-1}
if UTF8Enabled then
external_codepage:=utf8;
{$ifdef linux} {$ifdef linux}
if vcs_device>=0 then if vcs_device>=0 then
begin begin
@ -1082,6 +1114,16 @@ begin
for i:=low(terminal_names) to high(terminal_names) do for i:=low(terminal_names) to high(terminal_names) do
if copy(term,1,length(terminal_names[i]))=terminal_names[i] then if copy(term,1,length(terminal_names[i]))=terminal_names[i] then
cur_term_strings:=terminal_data[i]; 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 if cur_term_strings=@term_codes_freebsd then
console:=ttyFreeBSD; console:=ttyFreeBSD;
{$ifdef linux} {$ifdef linux}
@ -1090,16 +1132,22 @@ begin
{$endif} {$endif}
if cur_term_strings=@term_codes_linux then if cur_term_strings=@term_codes_linux then
begin begin
{Executed in case ttylinux is false (i.e. no vcsa), but if external_codepage<>utf8 then
TERM=linux.} begin
{Enable the VGA character set (codepage 437,850,....)} {Enable the VGA character set (codepage 437,850,....)}
fpwrite(stdoutputhandle,font_vga,sizeof(font_vga)); fpwrite(stdoutputhandle,font_vga,sizeof(font_vga));
external_codepage:=cp437; {Now default to codepage 437.} external_codepage:=cp437; {Now default to codepage 437.}
end;
end end
else else
{No VGA font :( } begin
fpwrite(stdoutputhandle,font_lat1,sizeof(font_lat1)); if external_codepage<>utf8 then
{ running on a remote terminal, no error with /dev/vcsa } 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} {$ifdef linux}
end; end;
{$endif} {$endif}