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