unit vnmvgahw;
{****************************************************************************}
{Unit VNMWGAHw - it is a part of graphics library VenomGFX.                  }
{It brings a interface for accessing font previously gadhered from VGA RAM or}
{VGA ROM.                                                                    }
{Both such font are processed for all three hardware sizes: 8,14 and 16px    }
{height.                                                                     }
{Internaly is called another unit: VNM_FV                                    }
{****************************************************************************}
{$IFDEF VER2}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF VER3}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF NEWFPC}{$CALLING OLDFPCCALL}{$ENDIF}
interface

const
VNM_VGAhw_sada8:pointer = nil;
VNM_VGAhw_sada14:pointer = nil;
VNM_VGAhw_sada16:pointer = nil;


implementation
uses GrpFile,GrpUtil,VenomGFX,VenomMng,VnmFnHlp,VNM_FV;

type
     PFontVGAhw = ^TFontVGAhw;
     TFontVGAhw = object
     font8,font14,font16:PObecnyFont;
     registrovan8,registrovan14,registrovan16:boolean;
     rez:string[24];
     Constructor Init;
     Function PocetSad:byte;
     Destructor Done;virtual;
     end;

Constructor TFontVGAhw.Init;
begin
font8:=nil;
font14:=nil;
font16:=nil;
registrovan8:=false;
registrovan14:=false;
registrovan16:=false;
end;


Function TFontVGAhw.PocetSad:byte;
begin
if font16=nil
   then PocetSad:=0
   else PocetSad:=3;
end;


Destructor TFontVGAhw.Done;
begin
end;


Function NejblizsiVelikost(a:longint):longint;
var b:longint;
begin
if a<=8 then b:=8 else
if a<=14 then b:=14 else b:=16;
NejblizsiVelikost:=b;
end;


Function VGAhw_font_setstyle(fnt:pointer;podfunkce,param1,param2:longint):pointer;
var hf,nhf:PObecnyFont;
    pw:PFontVGAhw;
    s2,sv:string;
    n,nn,m:byte;
    oo:boolean;
    l,okvelikost:longint;

begin
if podfunkce=2 then
   if (param1 and prop_fn)<>0
      then VNMFN_PROP_MODE:=true
      else VNMFN_PROP_MODE:=false;

if podfunkce<>1 then Exit(nil);

{Podfunkce 1:  PARAM1 zde znaci velikost}

hf:=fnt;
pw:=hf^.odkaz_na_kontejner;
if pw=nil then Exit(nil);


okvelikost:=NejblizsiVelikost(param1);

if okvelikost=8 then begin nhf:=pw^.font8;pw^.registrovan8:=true;end else
if okvelikost=14 then begin nhf:=pw^.font14;pw^.registrovan14:=true end else
   begin nhf:=pw^.font16;pw^.registrovan16:=true;end;

VGAhw_font_setstyle:=nhf;

{debug_vga_hw_PFontVGA:=PFontVGA(nhf^.fdata);}
end;



Function Load_VGAhw_font(s:string;size:byte):pointer;
{Predpokladem je, ze jsou spravne nastavene ukazatele
VNM_VGAhw_sada8, VNM_VGAhw_sada14 a VNM_VGAhw_sada16}
var a:byte;
    ok:boolean;
    vga8,vga14,vga16:PFontFV;
    pw:PFontVGAhw;
    p:pointer;
    cp437:boolean;

    zz:PZnak;

begin
for a:=1 to Length(s) do s[a]:=UpCase(s[a]);
{bud VGARAM._HW_ nebo VGAROM._HW_}
cp437:=s='VGAROM._HW_';

pw:=New(PFontVGAhw,Init);    {inicializace "skorapky"}
pw^.rez:=s;

pw^.font8:=New(PObecnyFont,Init);
pw^.font8^.odkaz_na_kontejner:=pw;
pw^.font8^.typzdroje:=1;
vga8:=New(PFontFV,Init);
vga8^.rez:=s;
vga8^.rukojet:=pw;
ok:=vga8^.Load_FV_from_PVGACharset_buffer(VNM_VGAhw_sada8,8);
pw^.font8^.fdata:=vga8;

pw^.font14:=New(PObecnyFont,Init);
pw^.font14^.odkaz_na_kontejner:=pw;
pw^.font14^.typzdroje:=1;
vga14:=New(PFontFV,Init);
vga14^.rez:=s;
vga14^.rukojet:=pw;
ok:=vga14^.Load_FV_from_PVGACharset_buffer(VNM_VGAhw_sada14,14);
pw^.font14^.fdata:=vga14;

pw^.font16:=New(PObecnyFont,Init);
pw^.font16^.odkaz_na_kontejner:=pw;
pw^.font16^.typzdroje:=1;
vga16:=New(PFontFV,Init);
vga16^.rez:=s;
vga16^.rukojet:=pw;
ok:=vga16^.Load_FV_from_PVGACharset_buffer(VNM_VGAhw_sada16,16);
pw^.font16^.fdata:=vga16;

if cp437 then
   begin
   vga8^.kodova_stranka:=437;
   vga14^.kodova_stranka:=437;
   vga16^.kodova_stranka:=437;
   end;

p:=VGAhw_font_setstyle(pw^.font16,1,size,0);
{pomoci velikosti se prepneme na pozadovanou znakovou sadu}

Load_VGAhw_font:=p;
end;


Function VGAhw_font_PrepChar(fnt:pointer;znak:word):pointer;
var hf:PObecnyFont;
begin
hf:=fnt;
VGAhw_font_PrepChar:=hf^.fdata^.PrepChar(znak);
end;



Procedure VGAhw_font_OutText(kam:pointer;x,y:longint;s:string;fnt:pointer;color:word);
var hf:PObecnyFont;
    pf:PFontFV;

begin
if fnt<>nil then
   begin
   hf:=fnt;
   pf:=PFontFV(hf^.fdata);
   VnmFnHlp_OutText(kam,x,y,s,pf,color);
   end;
end;


Function VGAhw_font_GetInfo(fnt:pointer;param1,param2:longint):longint;
var hf,hf2:PObecnyFont;
    pw:PFontVGAhw;
    i:longint;

begin
hf:=fnt;

if param1=101 then   {funkce Dej nejblizsi velikost k Param2}
   begin
   pw:=hf^.odkaz_na_kontejner;
   i:=NejblizsiVelikost(param2);
   Exit(i);
   end;

if param1=102 then   {funkce Dej odkaz na font s oznacenim Param2}
   begin
   pw:=hf^.odkaz_na_kontejner;
   i:=NejblizsiVelikost(param2);

   if i=8 then
      if pw^.registrovan8 then Exit(longint(pw^.font8)) else Exit(0) else
   if i=14 then
      if pw^.registrovan14 then Exit(longint(pw^.font14)) else Exit(0) else
      if pw^.registrovan16 then Exit(longint(pw^.font16)) else Exit(0);
   end;

i:=hf^.GetInfo(param1,param2);
VGAhw_font_GetInfo:=i;
end;


Function VGAhw_font_delete(fnt:pointer;mode:byte):boolean;
var hf,hf8,hf14,hf16:PObecnyFont;
    pf:PFontVGAhw;
begin
if mode=0 then Exit(false);   {nedovolime castecne odstraneni - jen kompletni}
hf:=fnt;
pf:=hf^.odkaz_na_kontejner;

hf8:=pf^.font8;
hf14:=pf^.font14;
hf16:=pf^.font16;

Dispose(hf8,Done);
Dispose(hf14,Done);
Dispose(hf16,Done);

VGAhw_font_delete:=true;
end;





Procedure Register_VGAhw_font_Loader;
begin
RegisterFontEngine('_HW_',
                   @Load_VGAhw_font,
                   @VGAhw_font_PrepChar,
                   @VGAhw_font_OutText,
                   @VGAhw_font_setstyle,
                   @VGAhw_font_GetInfo,
                   @VGAhw_font_delete);

end;




begin
Register_VGAhw_font_Loader;
end.
