mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-05-26 05:42:54 +02:00
486 lines
16 KiB
Plaintext
486 lines
16 KiB
Plaintext
{
|
||
$Id$
|
||
This file is part of the Free Pascal run time library.
|
||
Copyright (c) 1993,97 by the Free Pascal development team
|
||
|
||
See the file COPYING.FPC, included in this distribution,
|
||
for details about the copyright.
|
||
|
||
This program is distributed in the hope that it will be useful,
|
||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
||
**********************************************************************}
|
||
|
||
{***************************************************************************}
|
||
{ Textausgabe }
|
||
{***************************************************************************}
|
||
|
||
const
|
||
{ maximal 16 Vektorfonts unterst<73>tzen }
|
||
{ um mehr Fonts laden zu k”nnen, muá }
|
||
{ diese Variable erh”ht werden }
|
||
maxfonts = 16;
|
||
fontdivs:array[0..maxfonts]of integer=
|
||
(1,4,3,4,4,4,4,4,4,3,3,1,1,1,1,1,1);
|
||
|
||
type
|
||
pbyte = ^byte;
|
||
|
||
{$PACKRECORDS 1}
|
||
pfontdata = ^tfontdata;
|
||
|
||
tfontdata = record
|
||
filetyp : char;
|
||
nr_chars : word;
|
||
undefined1 : byte;
|
||
value_first_char : byte;
|
||
undefined2 : array[1..3] of byte;
|
||
dist_origin_top : shortint;
|
||
dist_origin_baseline : shortint;
|
||
dist_origin_bottom : shortint;
|
||
undefined3 : array[1..5] of byte;
|
||
end;
|
||
|
||
{$PACKRECORDS NORMAL}
|
||
|
||
tfontrec = record
|
||
name : string[8];
|
||
data : pointer;
|
||
header : pfontdata;
|
||
offsets : pword;
|
||
widths : pbyte;
|
||
instr : pbyte;
|
||
end;
|
||
|
||
var
|
||
fonts : array[1..maxfonts] of tfontrec;
|
||
installedfonts : longint;
|
||
|
||
{$I FONT.PPI}
|
||
|
||
{ gibt true zur<75>ck, wenn p auf eine g<>ltige Fontdatei zeigt }
|
||
|
||
function testfont(p : pointer) : boolean;
|
||
|
||
begin
|
||
testfont:=(pchar(p)^='P') and
|
||
(pchar(p+1)^='K') and
|
||
(pchar(p+2)^=#8) and
|
||
(pchar(p+3)^=#8);
|
||
end;
|
||
|
||
{ setzt die Hilfsdaten f<>r den Font mit der Nr. font }
|
||
{ der Zeiger data muá schon gesetzt sein }
|
||
|
||
function setupfont(font : word) : integer;
|
||
|
||
begin
|
||
setupfont:=grOK;
|
||
fonts[font].header:=fonts[font].data+$80;
|
||
if fonts[font].header^.filetyp<>'+' then
|
||
begin
|
||
setupfont:=grInvalidFont;
|
||
exit;
|
||
end;
|
||
fonts[font].offsets:=fonts[font].data+$90;
|
||
fonts[font].widths:=pbyte(fonts[font].offsets+fonts[font].header^.nr_chars*2);
|
||
fonts[font].instr:=fonts[font].widths+fonts[font].header^.nr_chars;
|
||
end;
|
||
|
||
function InstallUserFont(const FontFileName : string) : integer;
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
{ es muá kein Graphikmodus gesetzt sein! }
|
||
{ ist noch Platz f<>r einen Font ? }
|
||
if installedfonts=maxfonts then
|
||
begin
|
||
_graphresult:=grError;
|
||
exit;
|
||
end;
|
||
inc(installedfonts);
|
||
fonts[installedfonts].name:=FontFileName;
|
||
fonts[installedfonts].data:=nil;
|
||
InstallUserFont:=installedfonts;
|
||
end;
|
||
|
||
function RegisterBGIfont(font : pointer) : integer;
|
||
|
||
var
|
||
hp : pbyte;
|
||
b : word;
|
||
name : string[12];
|
||
|
||
begin
|
||
{ noch nicht garantiert, daá alles klappt }
|
||
RegisterBGIfont:=grInvalidFontNum;
|
||
{ es muá kein Graphikmodus gesetzt sein! }
|
||
if testfont(font) then
|
||
begin
|
||
hp:=pbyte(font);
|
||
{ Ende des Textheaders suchen }
|
||
while hp^<>$1a do
|
||
hp:=hp+1;
|
||
{ auf Start des Names springen }
|
||
hp:=hp+3;
|
||
{ Namen lesen }
|
||
name:='';
|
||
for b:=0 to 3 do
|
||
name:=name+char((hp+b)^);
|
||
{ richtigen Font suchen }
|
||
for b:=1 to installedfonts do
|
||
begin
|
||
if fonts[b].name=name then
|
||
begin
|
||
fonts[b].data:=font;
|
||
RegisterBGIfont:=grOK;
|
||
RegisterBGIfont:=setupfont(b);
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
RegisterBGIFont:=grInvalidFont;
|
||
end;
|
||
|
||
procedure GetTextSettings(var TextInfo : TextSettingsType);
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
textinfo:=akttextinfo;
|
||
end;
|
||
|
||
procedure OutText(const TextString : string);
|
||
var x,y:integer;
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
x:=curx; y:=cury;
|
||
OutTextXY(curx,cury,TextString);
|
||
{ wenn horizontal und linksb<73>ndig ausgegeben wird, dann }
|
||
{ Grafikcursor nachf<68>hren }
|
||
if (akttextinfo.direction=HorizDir) and
|
||
(akttextinfo.horiz=LeftText) then
|
||
inc(x,textwidth(TextString));
|
||
curx:=x; cury:=y; { LineTo manipuliert den GrafikCursor !! }
|
||
end;
|
||
|
||
procedure outtext(const charakter : char);
|
||
var s:string;
|
||
x,y:integer;
|
||
begin
|
||
s:=charakter;
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
x:=curx; y:=cury;
|
||
OutTextXY(curx,cury,s);
|
||
{ wenn horizontal und linksb<73>ndig ausgegeben wird, dann }
|
||
{ Grafikcursor nachf<68>hren }
|
||
{ if (akttextinfo.direction=HorizDir) and
|
||
(akttextinfo.horiz=LeftText) then }
|
||
inc(x,textwidth(s));
|
||
curx:=x; cury:=y; { LineTo manipuliert den GrafikCursor !! }
|
||
end;
|
||
|
||
procedure OutTextXY(x,y : integer;const TextString : string);
|
||
|
||
var
|
||
b1,b2 : shortint;
|
||
c,instr,mask : byte;
|
||
i,j,k : longint;
|
||
oldvalues : linesettingstype;
|
||
nextpos : word;
|
||
xpos,ypos,offs: longint;
|
||
FontPtr : Pointer;
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
|
||
{ wirkliche x- und y-Startposition berechnen }
|
||
if akttextinfo.direction=horizdir then
|
||
begin
|
||
case akttextinfo.horiz of
|
||
centertext : XPos:=(textwidth(textstring) shr 1);
|
||
lefttext : XPos:=0;
|
||
righttext : XPos:=textwidth(textstring);
|
||
end;
|
||
case akttextinfo.vert of
|
||
centertext : YPos:=(textheight(textstring) shr 1);
|
||
bottomtext : YPos:=0;
|
||
toptext : YPos:=textheight(textstring);
|
||
end;
|
||
end else
|
||
begin
|
||
case akttextinfo.horiz of
|
||
centertext : XPos:=(textheight(textstring) shr 1);
|
||
lefttext : XPos:=0;
|
||
righttext : XPos:=textheight(textstring);
|
||
end;
|
||
case akttextinfo.vert of
|
||
centertext : YPos:=(textwidth(textstring) shr 1);
|
||
bottomtext : YPos:=0;
|
||
toptext : YPos:=textwidth(textstring);
|
||
end;
|
||
end;
|
||
X:=X-XPos; Y:=Y+YPos;
|
||
XPos:=X; YPos:=Y;
|
||
|
||
if akttextinfo.font=DefaultFont then begin
|
||
y:=y-6;
|
||
c:=textwidth(textstring) div 8 - 1; { Charcounter }
|
||
FontPtr:=@defaultfontdata;
|
||
for i:=0 to c do begin
|
||
offs:=ord(textString[i+1]) shl 3; { Offset des Chars in Data }
|
||
for j:=0 to 7 do begin
|
||
mask:=$80;
|
||
b1:=defaultfontdata[offs+j]; { Offset der Charzeile }
|
||
xpos:=i shl 3+x;
|
||
for k:=0 to 7 do begin
|
||
if (b1 and mask) <> 0 then putpixel(xpos+k,j+y,aktcolor);
|
||
mask:=mask shr 1;
|
||
end;
|
||
end;
|
||
end;
|
||
end else
|
||
|
||
begin
|
||
{ Linienstil setzen }
|
||
getlinesettings(oldvalues);
|
||
setlinestyle(solidln,oldvalues.pattern,normwidth);
|
||
if akttextinfo.direction=vertdir then xpos:=xpos + Textheight(textstring);
|
||
curx:=xpos; cury:=ypos; x:=xpos; y:=ypos;
|
||
for i:=1 to length(textstring) do
|
||
begin
|
||
c:=byte(textstring[i]);
|
||
c:=c-fonts[akttextinfo.font].header^.value_first_char;
|
||
{ definiertes Zeichen ? }
|
||
if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then continue;
|
||
nextpos:=fonts[akttextinfo.font].offsets[c];
|
||
while true do
|
||
begin
|
||
b1:=fonts[akttextinfo.font].instr[nextpos];
|
||
nextpos:=nextpos+1;
|
||
b2:=fonts[akttextinfo.font].instr[nextpos];
|
||
nextpos:=nextpos+1;
|
||
instr:=((b1 and $80) shr 6)+((b2 and $80) shr 7);
|
||
b1:=b1 and $7f;
|
||
b2:=b2 and $7f;
|
||
{ Vorzeichen erweitern }
|
||
if (b1 and $40)<>0 then b1:=b1 or $80;
|
||
if (b2 and $40)<>0 then b2:=b2 or $80;
|
||
{ neue Stiftposition berechnen und skalieren }
|
||
if akttextinfo.direction=VertDir then
|
||
begin
|
||
xpos:=x-((b2*aktmultx) div aktdivx);
|
||
ypos:=y-((b1*aktmulty) div aktdivy);
|
||
end
|
||
else
|
||
begin
|
||
xpos:=x+((b1*aktmultx) div aktdivx) ;
|
||
ypos:=y-((b2*aktmulty) div aktdivy) ;
|
||
end;
|
||
case instr of
|
||
0 : break;
|
||
2 : begin curx:=xpos; cury:=ypos; end;
|
||
3 : begin line(curx,cury,xpos,ypos);
|
||
curx:=xpos; cury:=ypos;
|
||
end;
|
||
end;
|
||
end;
|
||
if akttextinfo.direction=VertDir then
|
||
y:=y-(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx)
|
||
else
|
||
x:=x+(fonts[akttextinfo.font].widths[c]*aktmultx div aktdivx) ;
|
||
end;
|
||
setlinestyle( oldvalues.linestyle, oldvalues.pattern, oldvalues.thickness);
|
||
end;
|
||
end;
|
||
|
||
procedure outtextxy(x,y: Integer;const charakter : char);
|
||
var s:string;
|
||
begin
|
||
s:=charakter;
|
||
outtextXY(x,y,s);
|
||
end;
|
||
|
||
function TextHeight(const TextString : string) : word;
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
if akttextinfo.font=DefaultFont
|
||
then TextHeight:=6+akttextinfo.charsize
|
||
else
|
||
TextHeight:=(((fonts[akttextinfo.font].header^.dist_origin_top-
|
||
fonts[akttextinfo.font].header^.dist_origin_bottom) * aktmulty) div aktdivy) ;
|
||
end;
|
||
|
||
function TextWidth(const TextString : string) : word;
|
||
var i,x : Integer;
|
||
c : byte;
|
||
begin
|
||
_graphresult:=grOk; x:=0;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
if akttextinfo.font = Defaultfont then
|
||
TextWidth:=length(TextString)*8*akttextinfo.charsize
|
||
else begin
|
||
for i:=1 to length(TextString) do begin
|
||
c:=byte(textstring[i]);
|
||
dec(c,fonts[akttextinfo.font].header^.value_first_char);
|
||
{ definiertes Zeichen ? }
|
||
if (c<0) or (c>=fonts[akttextinfo.font].header^.nr_chars) then
|
||
continue;
|
||
x:=x+fonts[akttextinfo.font].widths[c];
|
||
end;
|
||
TextWidth:=((x * aktmultx) div aktdivx) ;
|
||
end;
|
||
end;
|
||
|
||
procedure SetTextJustify(horiz,vert : word);
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
if (horiz<0) or (horiz>2) or
|
||
(vert<0) or (vert>2) then
|
||
begin
|
||
_graphresult:=grError;
|
||
exit;
|
||
end;
|
||
akttextinfo.horiz:=horiz;
|
||
akttextinfo.vert:=vert;
|
||
end;
|
||
|
||
procedure SetTextStyle(font,direction : word;charsize : word);
|
||
|
||
var
|
||
f : file;
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
{ Parameter auf G<>ltigkeit <20>berpr<70>fen }
|
||
if font>installedfonts then
|
||
begin
|
||
_graphresult:=grInvalidFontNum;
|
||
exit;
|
||
end;
|
||
akttextinfo.font:=font;
|
||
if (direction<>HorizDir) and (direction<>VertDir) then
|
||
direction:=HorizDir;
|
||
akttextinfo.direction:=direction;
|
||
akttextinfo.charsize:=charsize;
|
||
if (charsize <> usercharsize) then begin
|
||
aktmultx:=charsize;
|
||
aktdivx:=fontdivs[font];
|
||
aktmulty:=charsize;
|
||
aktdivy:=fontdivs[font];
|
||
end;
|
||
{ Fontdatei laden ? }
|
||
if (font>0) and not assigned(fonts[font].data) then
|
||
begin
|
||
assign(f,bgipath+fonts[font].name+'.CHR');
|
||
reset(f,1);
|
||
if ioresult<>0 then
|
||
begin
|
||
_graphresult:=grFontNotFound;
|
||
akttextinfo.font:=DefaultFont;
|
||
exit;
|
||
end;
|
||
getmem(fonts[font].data,filesize(f));
|
||
if not assigned(fonts[font].data) then
|
||
begin
|
||
_graphresult:=grNoFontMem;
|
||
akttextinfo.font:=DefaultFont;
|
||
exit;
|
||
end;
|
||
blockread(f,fonts[font].data^,filesize(f));
|
||
|
||
if testfont(fonts[font].data) then
|
||
_graphresult:=setupfont(font)
|
||
else
|
||
begin
|
||
_graphresult:=grInvalidFont;
|
||
akttextinfo.font:=DefaultFont;
|
||
freemem(fonts[font].data,filesize(f));
|
||
end;
|
||
close(f);
|
||
end;
|
||
end;
|
||
|
||
procedure SetUserCharSize(Multx,Divx,Multy,Divy : word);
|
||
|
||
begin
|
||
_graphresult:=grOk;
|
||
if not isgraphmode then
|
||
begin
|
||
_graphresult:=grnoinitgraph;
|
||
exit;
|
||
end;
|
||
aktmultx:=Multx;
|
||
aktdivx:=Divx;
|
||
aktmulty:=Multy;
|
||
aktdivy:=Divy;
|
||
end;
|
||
|
||
|
||
{
|
||
$Log$
|
||
Revision 1.1 1998-03-25 11:18:42 root
|
||
Initial revision
|
||
|
||
Revision 1.3 1998/01/26 11:58:41 michael
|
||
+ Added log at the end
|
||
|
||
|
||
|
||
Working file: rtl/dos/ppi/text.ppi
|
||
description:
|
||
----------------------------
|
||
revision 1.2
|
||
date: 1997/12/01 12:21:34; author: michael; state: Exp; lines: +14 -0
|
||
+ added copyright reference in header.
|
||
----------------------------
|
||
revision 1.1
|
||
date: 1997/11/27 08:33:51; author: michael; state: Exp;
|
||
Initial revision
|
||
----------------------------
|
||
revision 1.1.1.1
|
||
date: 1997/11/27 08:33:51; author: michael; state: Exp; lines: +0 -0
|
||
FPC RTL CVS start
|
||
=============================================================================
|
||
}
|