home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Monster Media 1994 #1
/
monster.zip
/
monster
/
PROG_PAS
/
XLIB_TP5.ZIP
/
UNITS
/
X_TEXT.PAS
< prev
Wrap
Pascal/Delphi Source File
|
1993-12-19
|
36KB
|
966 lines
{$G+}
unit X_Text;
(*
Text procedures.
****** XLIB - Mode X graphics library ****************
****** ****************
****** Written By Themie Gouthas ( C-Version ) ****************
****** Converted By Christian Harms in TP ****************
****** 16xn - Bigfont and pascalcode by Christian Harms ****************
Gouthas : egg@dstos3.dsto.gov.au or teg@bart.dsto.gov.au
Harms : harms@minnie.informatik.uni-stuttgart.de
Ok, we have two serveral user fonts ! How to handle ?
The old 8xn-fonts width could max. 8 Pixels draw in the width.
If FontType = 1, it is a 16x16-bigfont !
8xn- normal font structure :
Byte 0 : FirstChar
Byte 1 : 0 => 8xn Font
Byte 3 : CharHeight
Byte 4 : CHarWidth if zero, font will be variable
Blocks from FirstChar to n :
Byte0..Byte CharHeight-1 : CharacterByte horizontaly
Byte CharHeight : CharWidth, if Byte 4=0
UPDATE: Variable width fonts are now available (up to 8/16 pixels max)
If the Width byte in the font header is 0 then it is assumed that
the font is variable width. For variable width fonts each characters
data is followed by one byte representing the characters pixel width.
16xn-bigfont structure :
Byte 0 : FirstChar
Byte 1 : 1 => 16x16 Font
Byte 3 : CharHeight
Byte 4 : CHarWidth if zero, font will be variable
Index_Array : [FirstChar..134] : Word
Bit 0..11: (0..4095) Offset to begin of Chardata
if offset 0, Character not defined
-> CharWidth:=0
Bit 12..15: (0..15) CharWidth
Byte n..eof : all CharacterWord verticaly order by Index_Array
*)
interface
(* Init the Fontpointers for ROM8x8 and ROM8x14 (font 0 and 1). *)
procedure x_text_init;
(*---------------------------------------------------------------------- *)
(* x_set_font - Mode X Set current font for text drawing *)
(* *)
(* x_set_font(FontID:Word) *)
(* *)
(* PARAMETERS FontID 0 = VGA ROM 8x8 *)
(* 1 = VGA ROM 8x14 *)
(* 2 = User defined bitmapped font *)
(* *)
(* *)
(* WARNING: A user font must be registered before setting FontID 2 *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_set_font(FontId:Word);
(*---------------------------------------------------------------------- *)
(* x_register_userfont - Mode X register user font *)
(* *)
(* x_register_userfont(Var user_font); *)
(* *)
(* *)
(* NOTES registering a user font deregisters the previous user font *)
(* User fonts may be at most 8 or 16 pixels wide. *)
(* *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_register_userfont(Var FontToRegister);
(*---------------------------------------------------------------------- *)
(* x_char_put - Mode X Draw a text character at the specified location *)
(* *)
(* x_char_put(ch:Char;x,y,Color:Word) *)
(* *)
(* PARAMETERS ch char to draw *)
(* x,y screen coords at which to draw ch *)
(* Color Color of the text *)
(* *)
(* NOTES: Uses the current font settings. See x_Set_Font, x_text_init, *)
(* x_Register_UserFont *)
(* Not for userfont 16xn, see X-Char_Put16. *)
(* *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
function x_char_put (chr:Char;x,y,Color:Word):Byte; (* for mode 0-2 *)
(* like x_char_put, but only for 16xn-Font.
Selection will make by FontType in font structure by X_Write !!! *)
function x_Char_Put16(chr:Char;x,y,Color:Word):Byte;
(* Returns the Font_Height+1, to make Textlines . *)
function x_font_Height:Byte;
(* Returns the Charwidth, calculate it if var. width. (both user fonts) *)
function x_get_char_width(Chr:Char):Byte;
(* Write the String S to Pos. x,y in Color <color>. *)
procedure x_Write(x,y:Integer;Color:Byte;s:String); (* simply Text ! *)
(* Write Text with a Shadow , high - color of Text *)
(* low - color of Shadow-Text *)
procedure E_Write(x,y,high,low:Integer;s:String);
(* Write a Integer using E_Write. *)
procedure E_WriteInt(x,y,high,low:Integer;I:LongInt);
(* Write a Real using E_Write. *)
procedure E_WriteReal(x,y,high,low:Integer;R:Real;f1,f2:Byte);
(* Write a Text with serverals Textcolors.
New Colors are included in the String : ... «Colornumber» .
With the character « (ALT-174) begin the Value, and ends with » (ALT-175)*)
procedure E_WriteColor(x,y,high,low:Integer;s:String);
const All_Char = 0;
Only_Digit = 1; (* if E_Read_Mode:=Only_Digit, it gets onl digits ! *)
Only_FileName = 2; (* it gets only characters for filenames ! *)
(* Look in E_ReadInt for exapmle. *)
var E_Read_Mode : Byte; (* Mask for E_Read. , see const here *)
(* Read the String s, (edit with Backspace) in the Box between x and MaxX,
- s could have some default characters
- abort with ESC, S:=''
- first pressed BackSpace, default S will be cleared *)
procedure E_Read(x,y,MaxX,FontColor,BackColor:Integer;var s:String);
(* Make a Input-Mask like : [ Filename : Oldname< ]
- High,low are colors for the name-string
- RHigh,RBack are the colors for the Inputstring in E_Read *)
procedure E_Input(x,y,MaxX,High,low,RHigh,RBack:Word;S:String;var S2:String);
(* Read a Integer/LongInt - see params in E_Read *)
procedure E_ReadInt(x,y,MaxX,FontColor,BackColor:Integer;var I:LongInt);
(* Make a Input-Mask for a Integer/LongInt - see params in E_Input. *)
procedure E_InputInt(x,y,MaxX,High,low,RHigh,RBack:Word;S:String;var I:LongInt);
(* Draw a Button , used by unit X_Button. *)
procedure No_Button_Write(x,y,Box_Bright,Box_dark,Box_back,
high,low:Integer;s:String);
(* The same like No_Button_Write, Colors are defined by Gray0..Gray5 in X_Const.*)
procedure No_Button_Write_Gray(x,y:Integer;S:String);
(* Draw a Button like a pressed Button, used by Unit X_Button *)
procedure Press_Button_Write(x,y,Box_Bright,Box_dark,Box_back,
high,low:Integer;s:String);
(* The same like Press_Button_Write, Colors are Gray0..Gray5 in X_Const. *)
procedure Press_Button_Write_Gray(x,y:Integer;s:String);
(* Setzt links und rechts so viele Leerzeichen, damit Breite erreicht wird. *)
(* Fills on left and right space until width is reached. *)
function center(width:Word;S:String):String;
function str(X:LongInt):String; (* the same use like TP-str,only as function *)
(* Length of the String in Pixelrows. *)
function x_length(S:String):Word;
(* Length of the LongInt, converted in String, in Pixelrows. *)
function x_lengthInt(I:LongInt):Word;
implementation
uses X_Const,X_Main,X_Keys,My_Asm,X_Rect;
var FontDriverActive: Byte;
FontMode : Byte;
CharHeight : Byte;
CharWidth : Byte;
FontType : Byte;
FontPtr : Pointer;
FirstChar : Byte;
UserFontPtr : Pointer;
UserChHeight : Byte;
UserChWidth : Byte;
UserFirstCh : Byte;
UserFontType : Byte;
F8x8Ptr : Pointer;
F8x14Ptr : Pointer;
(* This is a look up table for the mirror image of a byte eg *)
(* a byte with the value 11001010 has a corresponding byte in the table *)
(* 01010011. This is necessary as the VGA rom font bits are the reverse *)
(* order of what we need for the Mode X. If you know a better-faster way *)
(* TELL ME! *)
const MirrorTable : Array[0..255] of Byte = (
0,128, 64,192, 32,160, 96,224, 16,144, 80,208, 48,176,112,240,
8,136, 72,200, 40,168,104,232, 24,152, 88,216, 56,184,120,248,
4,132, 68,196, 36,164,100,228, 20,148, 84,212, 52,180,116,244,
12,140, 76,204, 44,172,108,236, 28,156, 92,220, 60,188,124,252,
2,130, 66,194, 34,162, 98,226, 18,146, 82,210, 50,178,114,242,
10,138, 74,202, 42,170,106,234, 26,154, 90,218, 58,186,122,250,
6,134, 70,198, 38,166,102,230, 22,150, 86,214, 54,182,118,246,
14,142, 78,206, 46,174,110,238, 30,158, 94,222, 62,190,126,254,
1,129, 65,193, 33,161, 97,225, 17,145, 81,209, 49,177,113,241,
9,137, 73,201, 41,169,105,233, 25,153, 89,217, 57,185,121,249,
5,133, 69,197, 37,165,101,229, 21,149, 85,213, 53,181,117,245,
13,141, 77,205, 45,173,109,237, 29,157, 93,221, 61,189,125,253,
3,131, 67,195, 35,163, 99,227, 19,147, 83,211, 51,179,115,243,
11,139, 75,203, 43,171,107,235, 27,155, 91,219, 59,187,123,251,
7,135, 71,199, 39,167,103,231, 23,151, 87,215, 55,183,119,247,
15,143, 79,207, 47,175,111,239, 31,159, 95,223, 63,191,127,255 );
var MirrorTableOffs :Word;
(*---------------------------------------------------------------------- *)
(* x_text_init - Initializes the Mode X text driver and sets the *)
(* default font (VGA ROM 8x8) *)
(* *)
(* x_text_init() *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_text_init; assembler;
asm
push bp
mov [FontDriverActive],TRUE
mov ax,$1130 (* AH = BIOS generator function *)
(* AL = BIOS get font pointer subfunction*)
push ax (* Save Video interrupt function parameters *)
mov bh,3 (* Select 8x8 VGA ROM font *)
int 10h (* Call BIOS video interrupt *)
mov word ptr [F8x8Ptr],bp (* Save 8x8 Font address in FontPtr table*)
mov word ptr [F8x8Ptr+2],es
mov word ptr [FontPtr],bp (* Default font = 8x8 ROM font *)
mov word ptr [FontPtr+2],es
pop ax (* Recall Video interrupt function parameters *)
mov bh,2 (* Select 8x14 VGA ROM font *)
int 10h (* Call BIOS video interrupt *)
mov word ptr [F8x14Ptr],bp (* Save 8x14 Font address in FontPtr table *)
mov word ptr [F8x14Ptr+2],es
mov al,8
mov [CharHeight],al (* Set the font character heights *)
mov [CharWidth] ,al (* Set the font character widths *)
mov dx,offset MirrorTable (* Initialize mirror table offset *)
mov [MirrorTableOffs],dx
xor ax,ax
mov [FontMode],al
pop bp
end;
(*---------------------------------------------------------------------- *)
(* x_set_font - Mode X Set current font for text drawing *)
(* *)
(* x_set_font(FontID:Word) *)
(* *)
(* PARAMETERS FontID 0 = VGA ROM 8x8 *)
(* 1 = VGA ROM 8x14 *)
(* 2 = User defined bitmapped font *)
(* *)
(* *)
(* WARNING: A user font must be registered before setting FontID 2 *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_set_font(FontId:Word); assembler;
asm
xor dx,dx (* Clear DX - Mirror table offset (0 for non ROM fonts) *)
mov cx,FontID
mov [FontMode],cl
cmp cx,2
jne @@not_userfont (* Do we have a user font *)
mov ax,word ptr [UserFontPtr] (* Yes - Activate it *)
mov word ptr [FontPtr],ax
mov ax,word ptr [UserFontPtr+2]
mov word ptr [FontPtr+2],ax
mov al,[UserChHeight]
mov [CharHeight],al (* Set the font character heights *)
mov al,[UserChWidth]
mov [CharWidth],al (* Set the font character heights *)
mov al,[UserFirstCh]
mov [FirstChar],al
mov al,[UserFontType]
mov [FontType],al
jmp @@done
@@not_userfont: (* We have a ROM font *)
mov dx,offset MirrorTable
mov [CharWidth],8 (* Set the font character widths *)
mov [FirstChar],0 (* Character sets start at ascii 0 *)
cmp cx,1 (* Do we have an 8x14 ROM font *)
jne @@not_8x14font (* No, we have 8x8 - jump *)
mov ax,word ptr [F8x14Ptr] (* Yes Activate it *)
mov word ptr [FontPtr],ax
mov ax,word ptr [F8x14Ptr+2]
mov word ptr [FontPtr+2],ax
mov [CharHeight],14 (* Set the font character heights *)
jmp @@done
@@not_8x14font:
mov ax,word ptr [F8x8Ptr] (* Activate the 8x8 ROM Font *)
mov word ptr [FontPtr],ax
mov ax,word ptr [F8x8Ptr+2]
mov word ptr [FontPtr+2],ax
mov [CharHeight],8 (* Set the font character heights *)
@@done:
mov [MirrorTableOffs],dx
end;
(*---------------------------------------------------------------------- *)
(* x_register_userfont - Mode X register user font *)
(* *)
(* x_register_userfont(Var user_font); *)
(* *)
(* *)
(* NOTES registering a user font deregisters the previous user font *)
(* User fonts may be at most 8 pixels wide *)
(* *)
(* *)
(* USER FONT STRUCTURE *)
(* *)
(* Word: ascii code of first char in font *)
(* Byte: Height of chars in font *)
(* Byte: Width of chars in font *)
(* n*h*Byte: the font data where n = number of chars and h = height *)
(* of chars *)
(* *)
(* WARNING: The onus is on the program to ensure that all characters *)
(* drawn whilst this font is active, are within the range of *)
(* characters defined. *)
(* *)
(* *)
(* UPDATE: Variable width fonts are now available (up to 8 pixels max) *)
(* If the Width byte in the font header is 0 then it is assumed that *)
(* the font is variable width. For variable width fonts each characters *)
(* data is followed by one byte representing the characters pixel width. *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
procedure x_register_userfont(Var FontToRegister); assembler;
asm
mov ax,word ptr [FontToRegister]
mov bx,word ptr [FontToRegister+2]
add ax,4
mov word ptr [UserFontPtr],ax
mov word ptr [UserFontPtr+2],bx
push ds
lds si,[FontToRegister]
lodsw
mov bx,ax
lodsw
pop ds
mov [UserChHeight],al
mov [UserChWidth],ah
mov [UserFirstCh],bl
mov [UserFontType],bh
end;
function x_get_char_width(Chr:Char):Byte; assembler;
asm
xor ah,ah
mov al,[CharWidth]
or al,al
jz @@NotFixed
jmp @ende
@@NotFixed:
cmp FontType,1
je @Font16xn
push si
mov al,[CharHeight]
mov bx,ax
inc al
mov dl,[Chr] (* User fonts may have incomplete charsets *)
sub dl,[FirstChar] (* this compensates for fonts not starting at *)
(* ascii value 0 *)
mul dl (* Mult AX by character to draw giving offset *)
(* of first character byte in font table *)
add ax,bx
les si,dword ptr [FontPtr]
add si,ax
xor ah,ah
mov al,es:[si]
pop si
jmp @ende
@Font16xn:
push si
xor bx,bx
mov bl,Chr
sub bl,FirstChar
dec bl (* Dec, because font begins with #1 *)
shl bx,1
les si,dword ptr [FontPtr]
mov ax,es:[si+bx] (* Get MaskOfs and Width *)
shr ax,12 (* extract Width *)
inc al
pop si
@ende:
{ and ax,$000f}
end;
{$F+}
(*---------------------------------------------------------------------- *)
(* x_char_put - Mode X Draw a text character at the specified location *)
(* *)
(* x_char_put(ch:Char;x,y,Color:Word) *)
(* *)
(* PARAMETERS ch char to draw *)
(* x,y screen coords at which to draw ch *)
(* Color Color of the text *)
(* *)
(* NOTES: Uses the current font settings. See SetFont, InitTextDriver, *)
(* RegisterUserFont *)
(* *)
(* WARNING: InitTextDriver must be called before using this function *)
(* *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
function x_char_put(chr:Char;x,y,Color:Word):Byte; assembler;
var ScreenInc,Hold:Word;
asm
push ds
cld
mov ax,[ScrnLogicalByteWidth] (* AX = Virtual screen width *)
mov bx,ax (* copy Virt screen width and decrement *)
sub bx,3 (* by the max number of bytes (whole or part) *)
(* that a character row may occupy on the screen *)
mov [ScreenInc],bx (* Save it to the local stack var. SceenInc *)
mul [Y] (* Find the starting dest. screen address of *)
mov di,[X] (* the character to draw *)
mov cx,di
shr di,2
add di,ax
add di,[ScreenOfs] (* Dont forget to compensate for page *)
mov ax,SCREEN_SEG (* ES:DI -> first screen dest. byte of char *)
mov es,ax
and cx,3 (* CH = 0, CL = Plane of first pixel *)
mov bx,[MirrorTableOffs] (* set BX to offset of mirror table for XLAT *)
mov al,[CharHeight] (* AL = Character height, AH = 0 *)
xor ah,ah
mov ch,al (* CH = Character height *)
cmp [CharWidth],0
jne @@NoWidthByte
inc al
@@NoWidthByte:
mov dl,Chr (* User fonts may have incomplete charsets*)
sub dl,[FirstChar] (* this compensates for fonts not starting at *)
(* ascii value 0 *)
mul dl (* Mult AX by character to draw giving offset *)
(* of first character byte in font table *)
lds si,dword ptr [FontPtr] (* DS:SI -> beggining of required font *)
add si,ax (* DS:SI -> first byte of req. char *)
mov dx,SC_INDEX (* Prepare for VGA out's *)
@@MainLoop:
lodsb (* load character byte into AL *)
or al,al
jz @@NoCharPixels (* Dont bother if no pixels to draw *)
or bx,bx (* if BX=0 -> User font, so no need to mirror data *)
jz @@DontMirror
push ds
mov dx,seg @data (* Set DS to the Mirror lookup table's segment *)
mov ds,dx (* - BX should already contain the offset addr of table *)
xlat (* AL is now replaced by the corresponding table entry *)
pop ds (* Restore previous data segment *)
mov dx,SC_INDEX (* Restore DX *)
@@DontMirror:
xor ah,ah (* shift the byte for the dest plane and save it *)
shl ax,cl
mov [Hold],ax
mov ah,al (* output high nibble of first byte of shifted char *)
and ah,0fh (* 4 pixels at a time ! *)
jnz @@p1 (* if nibble has pixels, draw them *)
inc di (* otherwise go to next nibble *)
jmp @@SecondNibble
@@p1:
mov al,MAP_MASK
out dx,ax
mov al,byte ptr [Color]
stosb
@@SecondNibble:
(* output low nibble of first byte of shifted char *)
mov ax,[Hold]
shl ax,4
and ah,0fh
jnz @@p2
inc di
jmp @@ThirdNibble
@@p2:
mov al,MAP_MASK
out dx,ax
mov al,byte ptr [Color]
stosb
@@ThirdNibble:
mov ax,[Hold] (* output high nibble of last byte of shifted char *)
and ah,0fh
jnz @@p3
inc di
jmp @@NextCharRow
@@p3:
mov al,MAP_MASK (* completing the drawing of one character row *)
out dx,ax
mov al,byte ptr [Color]
stosb
@@NextCharRow:
add di,[ScreenInc] (* Now move to the next screen row and do the same *)
dec ch (* any remaining character bytes *)
jnz @@MainLoop
@@done:
pop es
mov ah,0
mov al,es:[CharWidth] (* return the character width (for string fuctions *)
or al,al
jnz @@FixedSpacing (* using this character drawing function). *)
lodsb
@@FixedSpacing:
mov bx,es
mov ds,bx
jmp @ende
@@NoCharPixels:
add di,3
add di,[ScreenInc] (* Now move to the next screen row and do the same *)
dec ch (* any remaining character bytes *)
jnz @@MainLoop
jmp @@done
@ende:
end;
(*---------------------------------------------------------------------- *)
(* x_char_put16 - Mode X Draw a text character at the specified location *)
(* *)
(* x_char_put16(ch:Char;x,y,Color:Word):Byte; *)
(* *)
(* Returns the Char_width. *)
(* *)
(* PARAMETERS ch char to draw *)
(* x,y screen coords at which to draw ch *)
(* Color Color of the text *)
(* *)
(* NOTES: Uses the current font settings. See SetFont, InitTextDriver, *)
(* RegisterUserFont *)
(* *)
(* WARNING: InitTextDriver must be called before using this function *)
(* *)
(* *)
(* Written by Themie Gouthas *)
(*---------------------------------------------------------------------- *)
function x_Char_Put16(chr:Char;x,y,Color:Word):Byte; assembler;
var Save_Ofs,X_Index,SLBW:Word;
FontH,FontW:Byte;
asm
mov al,CharHeight
inc al
mov FontH,al
mov ax,ScrnLogicalByteWidth
mov SLBW,ax
mov ax,x
mov X_Index,ax
mov al,FirstChar
sub Chr,al
dec Chr (* Dec, because font begins with #1 *)
mov ax,SCREEN_SEG
mov es,ax
mov ax,[y]
mov bx,SLBW
mul bx
add ax,ScreenOfs
{ mov di,ax }
mov Save_Ofs,ax (* es:[di] points into the VRAM *)
push ds
lds si,dword ptr [FontPtr] (* Pointer to UserFont 16x16 *)
xor bx,bx
mov bl,Chr (* Calculate FirstCharOfs *)
shl bx,1
mov ax,ds:[si+bx] (* Get MaskOfs and Width *)
mov bx,ax
shr bx,12
mov FontW,bl (* save FontWidth *)
and ax,$0FFF
add si,ax (* ds:[si] points to first Mask-Word *)
or ax,ax
jz @Done (* If Offset=0 -> done,because Char not. def. *)
@X_Loop:
mov ax,[X_Index]
shr ax,2
add ax,Save_Ofs
mov di,ax (* Screen - offset *)
mov cx,[X_Index]
and cl,3
mov ax,1
shl ax,cl
mov ah,al
mov al,MAP_MASK
mov dx,SC_INDEX
out dx,ax (* select pixelplane *)
lodsw (* Get maskword from ds:[si] *)
xor ch,ch
mov cl,FontH
mov dx,SLBW
@Y_Loop:
shr ax,1
jnc @no_Point (* if no bit set, no_point *)
mov bl,Byte ptr [Color]
mov es:[di],bl (* Write Color to screen *)
@no_Point:
add di,dx (* Screenpointer to next line *)
loop @Y_Loop
mov ax,[X_Index]
inc ax
mov [X_Index],ax
sub ax,[x]
cmp al,FontW
jne @X_Loop
inc ax (* Space between two Characters *)
@Done:
pop ds
end;
{$F-}
function x_font_Height:Byte;
begin;
x_font_Height:=CharHeight+1; (* for textline output *)
end;
function str(X:LongInt):String;
var S:String;
begin;
System.str(x,s);
str:=s;
end;
function x_length(S:String):Word;
var i,l:Word;
s1:String;IsC:Boolean;
begin;
if pos('«',S)>0 then (* If a string for WriteColor, delete all «x» *)
begin;
s1:='';IsC:=false;
for i:=1 to length(s) do
begin;
if IsC=false then
if S[i]='«' then IsC:=True
else s1:=s1+s[i]
else if s[i]='»' then IsC:=False;
end;
s:=s1;
end;
l:=0;
for i := 1 to length(s) do
if s[i]>#127 then
case s[i] of
'ü':s[i]:=chr(132); 'Ü':s[i]:=chr(133);
'ä':s[i]:=chr(128); 'Ä':s[i]:=chr(129);
'ö':s[i]:=chr(130); 'Ö':s[i]:=chr(131);
'ß':s[i]:=chr(134);
else s[i]:=' ';
end;
for i:=1 to length(s) do
begin;
l:=l+x_get_char_width(s[i]);
end;
x_length:=l;
end;
function x_lengthInt(I:LongInt):Word;
var s:string;
begin;
x_lengthInt:=x_length(Str(i));
end;
function center(width:Word;S:String):String;
begin;
while (x_length(' '+s+' ')<=width) do s:=' '+s+' ';
center:=s;
end;
procedure X_Write(x,y:Integer;Color:Byte;s:String);
var j,j_End,l,Adr_Ofs:Word;
a:Char;
My_Put:function(a:Char;x,y,color:Word):Byte;
begin;
if (FontMode<2)or(FontType=0) then My_Put:=X_Char_Put
else My_Put:=X_Char_Put16;
for j := 1 to length(s) do
begin;
if (s[j]>#127)and(FontMode>1) then case s[j] of
'ü' : s[j]:=chr(132); 'Ü' : s[j]:=chr(133);
'ä' : s[j]:=chr(128); 'Ä' : s[j]:=chr(129);
'ö' : s[j]:=chr(130); 'Ö' : s[j]:=chr(131);
'ß' : s[j]:=chr(134); else s[j]:=' ';
end;
x:=x+My_Put(s[j],x,y,color );
end;
end;
procedure E_Write(x,y,high,low:Integer;s:String);
begin;
X_Write(x+1,y+1,low,s);
X_Write(x,y,high,s);
end;
procedure E_WriteInt(x,y,high,low:Integer;I:LongInt);
var s:String;
begin;
E_Write(x,y,high,low,str(i));
end;
procedure E_WriteReal(x,y,high,low:Integer;R:Real;f1,f2:Byte);
var s:String;
begin;
system.str(r:f1:f2,s);
E_Write(x,y,high,low,s);
end;
(* Mit «Farbwert» wird die high-Farbe für die folgenden Zeichen def. *)
procedure E_WriteColor(x,y,high,low:Integer;s:String);
var i,j,f:Byte;
c:Integer;
s1:String;
begin;
s1:='';f:=High;
for i:=1 to length(s) do
begin;
if s[i]<>'«' then s1:=s1+s[i]
else
begin;
E_Write(x,y,f,low,s1);
Inc(x,x_length(s1));
s1:='';Inc(i);
while (i<=length(S))and(S[i]<>'»')do begin;s1:=s1+s[i];Inc(i);end;
val(s1,j,c);
if c<>0 then f:=High else f:=j;
s1:='';
end;
end;
E_Write(x,y,f,low,s1);
end;
(* Used by No_Button_Pressed,Press_Button_Write *)
procedure Button_Write(x,y,Box_bright,Box_dark,box_back,
high,low,Plus:Integer;s:String);
var x2:Integer;
begin
x2:=x+x_length(s);
Shadow_Box(x,y,x2+2,y+x_font_Height+1,Box_Bright,box_Back,Box_dark);
E_WriteColor(x+Plus+1,y+Plus+1,high,low,s);
end;
procedure No_Button_Write(x,y,Box_Bright,Box_dark,Box_back,
high,low:Integer;s:String);
begin;
Button_Write(x,y,Box_Bright,Box_dark,Box_back,high,low,0,s);
end;
procedure No_Button_Write_Gray(x,y:Integer;S:String);
begin;
No_Button_Write(x,y,Gray3,Gray5,Gray4,Gray0,Gray2,s);
end;
procedure Press_Button_Write(x,y,Box_Bright,Box_dark,Box_back,
high,low:Integer;s:String);
begin;
Button_Write(x,y,Box_dark,Box_Bright,Box_back,high,low,1,s);
end;
procedure Press_Button_Write_Gray(x,y:Integer;s:String);
begin;
Press_Button_Write(x,y,Gray3,Gray5,Gray4,Gray0,Gray2,s);
end;
procedure E_Read(x,y,MaxX,FontColor,BackColor:Integer;var s:String);
var a:Char;
first:Boolean;
s1:String;
i:Word;
begin;
s1:=s;
first:=TRUE;
if MaxX-12<x then Exit;
while (x_length(s+#7)>MaxX-X) do s:=copy(s,1,length(s)-1);
Box(x-1,y-1,MaxX,y+x_font_Height,FontColor);
X_Write(x,y,BackColor,s+#7);
a:=ReadKeys;
while (a<>#13)and(a<>#27) do
begin;
case a of
#0:Begin;a:=ReadKeys;end;
#8:if first then s:='' else s:=copy(s,1,length(s)-1);
#32..#127,'ü','Ü','ä','Ä','ö','Ö','ß':
case E_Read_Mode of
All_Char : s:=s+a;
Only_Digit: if a in ['.','-','+','0'..'9'] then s:=s+a;
Only_FileName : if not (a in [',','"','','/','<','>']) then s:=s+a;
end;
end;
while (x_length(s+#17)>MaxX-X) do s:=copy(s,1,length(s)-1);
if first or (length(s)<4) then
begin;
Box(x-1,y-1,MaxX,y+x_font_Height,BackColor);
X_Write(x,y,FontColor,s+#17);
end
else begin;
i:=x_length(copy(s,1,length(s)-1));
Box(x+i,y-1,MaxX,y+x_font_Height,BackColor);
X_Write(x+i,y,FontColor,copy(s,length(s),255)+#17);
end;
first:=False;
a:=ReadKeys;
end;
if a=#27 then
begin;
s:='';
Box(x-1,y-1,MaxX,y+x_font_Height,BackColor);
X_Write(x,y,FontColor,s);
end
else Box(x+x_length(copy(s,1,length(s))),y-1,MaxX,y+x_font_Height,BackColor);
end;
procedure E_Input(x,y,MaxX,High,low,RHigh,RBack:Word;S:String;var S2:String);
begin;
E_Write(x,y,High,low,s);
Inc(x,x_length(s));
E_Read(x,y,MaxX,Rhigh,Rback,s2);
end;
procedure E_ReadInt(x,y,MaxX,FontColor,BackColor:Integer;var I:LongInt);
var s:String;
C:Integer;
begin;
System.str(i,s);
E_Read_Mode:=Only_Digit;
E_Read(x,y,MaxX,FontColor,BackColor,s);
E_Read_Mode:=All_Char;
val(s,i,c);
end;
procedure E_InputInt(x,y,MaxX,High,low,RHigh,RBack:Word;S:String;var I:LongInt);
begin;
E_Write(x,y,High,low,s);
Inc(x,x_length(s));
E_ReadInt(x,y,MaxX,Rhigh,Rback,i);
end;
begin;
E_Read_Mode := All_Char;
FontMode:=0;
end.