unit vnm_wfn;
{****************************************************************************}
{Unit VNM_WFN - it is a addon unit for graphics library VenomGFX.            }
{It brings a loader for fonts in WFN format.                                 }
{In the fact, WFN format is a collection of multiple FN fonts in single      }
{archive, witch is in GRP format but renamed to .WFN extension.              }
{****************************************************************************}
{$IFDEF VER2}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF VER3}{$DEFINE NEWFPC}{$ENDIF}
{$IFDEF NEWFPC}{$CALLING OLDFPCCALL}{$ENDIF}
interface


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

type
     PFontWFN = ^TFontWFN;
     TFontWFN = object
     mapa:PGrpMapa;
     rez:string[24];

     {akt_vga_sada:byte;}
     {Definice Fontu je ve zdedenem ObecFont}

     Constructor Init;
     Function PocetSad:byte;
     Destructor Done;virtual;
     end;


Constructor TFontWFN.Init;
begin
mapa:=nil;
{akt_vga_sada:=0;}
end;


Function TFontWFN.PocetSad:byte;
begin
if mapa=nil
   then PocetSad:=0
   else PocetSad:=mapa^.num;
end;


Destructor TFontWFN.Done;
begin
mapa^.Done;
Dispose(mapa);
end;


Function WFN_font_setstyle(fnt:pointer;podfunkce,param1,param2:longint):pointer;
var hf,nhf:PObecnyFont;
    {pf:PFontVGA;}
    pw:PFontWFN;
    pf:PFontFN;
    s2,sv:string;
    l,okindex,okvelikost:longint;
    okd:longint;
    prac:PGrpMapa;

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);


s2:=DoplnJmenoFontu(pw^.rez);

prac:=pw^.mapa;

okindex:=prac^.Nejblizsi_k_oznaceni(param1);
okvelikost:=prac^.zaznam^[okindex].oznaceni;
sv:=prac^.zaznam^[okindex].nazev;             {nazev souboru z GRP archivu}

nhf:=Load_FN_font(s2+'#'+sv,okvelikost); {Nacte do PObecnyFont/PFontVGA}
{jsou vyplnene FDATA=... a TYPZDROJE=2}

nhf^.typzdroje:=3;     {opravime, protoze jsem z bitmapoveho kontejneru}
nhf^.typ_kontejneru_detail:=1;  {GRP format}
nhf^.odkaz_na_kontejner:=pw;   {vazba na zastresujici strukturu WGA}


pf:=PFontFN(nhf^.fdata);

okd:=pw^.mapa^.info[1];

if okd>0 then
   pf^.kodova_stranka:=okd;  {zaznam Info1 je kodova stranka}
                             {muzu tak prebit vnitrni udaj}

pf^.vel:=okvelikost;   {prebijeme "exportni" udaj o velikosti (SOSU samozrejme nemenim)}
pf^.rukojet:=nhf;
pw^.mapa^.zaznam^[okindex].odkaz:=nhf;
WFN_font_setstyle:=nhf;
end;



Function Load_WFN_font(s:string;size:longint):pointer;
var a,b:byte;
    grp:TGrpStream;
    s2,n:string;
    l:longint;
    oo:boolean;

    temphf:PObecnyFont;

    temppf:PFontFN;
    pw:PFontWFN;
    prac:PGrpMapa;
    p:pointer;

begin
for a:=1 to Length(s) do s[a]:=UpCase(s[a]);

s2:=DoplnJmenoFontu(s);
grp.Init(s2,grpOpenRead);
if grp.status<>grpOK then begin Grp.Done;Exit(nil);end;

if grp.Jsem_ja_grp=false then
   begin grp.Done;Exit(nil);end;

grp.Done;

{Zde vime, ze soubor existuje a ze jde o GRP archiv}
pw:=New(PFontWFN,Init);    {inicializace "skorapky"}
pw^.rez:=NazevBezCesty(s);;
New(pw^.mapa);             {inicializujeme pamet pro mapu}

oo:=Vytahni_mapovy_soubor_GRP(s2,pw^.mapa^);  {vyplnime mapu z mapoveho souboru}
if oo=false then Exit(nil);        {Mapovy soubor je povinny. Nebyl? Konec.}

temphf:=New(PObecnyFont,Init);          {inicializuji pahyl fontu...}
temphf^.odkaz_na_kontejner:=pw;         {...ktery ovsem napojim na Mapu}
{nicmene, neobtezuju se s napojovanim na zadne PFontVGA ci PFontWGA}

prac:=pw^.mapa;

p:=WFN_font_setstyle(temphf,1,size,0);
{pomoci pahylu se propojime s Mapou a nahrajeme pozadovanou velikost}
Dispose(temphf,Done);                   {a tento pahyl nyni smazu}
Load_WFN_font:=p;
end;


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


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

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


Function WFN_Font_GetInfo(fnt:pointer;param1,param2:longint):longint;
var hf,hf2:PObecnyFont;
    pw:PFontWFN;
    mp:PGRPmapa;
    i,j:longint;
    s:string;

begin
hf:=fnt;

if param1=101 then   {funkce Dej nejblizsi velikost k Param2}
   begin
   pw:=hf^.odkaz_na_kontejner;
   mp:=pw^.mapa;
   i:=mp^.Nejblizsi_k_oznaceni(byte(param2));
   j:=mp^.zaznam^[i].oznaceni;
   Exit(j);
   end;

if param1=102 then   {funkce Dej odkaz na font s oznacenim Param2}
   begin
   pw:=hf^.odkaz_na_kontejner;
   mp:=pw^.mapa;
   i:=mp^.Index_podle_oznaceni(byte(param2));
   hf2:=mp^.zaznam^[i].odkaz;
   Exit(longint(hf2));
   end;

if param1=3 then     {vygeneruj retezec, ktery obsahuje vsechny dostupne}
   begin             {velikosti fontu}
   pw:=hf^.odkaz_na_kontejner;
   mp:=pw^.mapa;
   s:=mp^.Dej_retezec_s_velikostmi;
   Move(s,pointer(param2)^,Length(s)+1);
   Exit(-1);
   end;

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


Function WFN_Font_delete(fnt:pointer;mode:byte):boolean;
var hf:PObecnyFont;
    pf:PFontWFN;      {kontejnerova cast}
begin
hf:=fnt;
if mode=0
   then Dispose(hf,Done)    {Smaze i hf^.FData  (typu PFontFN), ale nikoliv kontejner}
   else begin {mode 1}
   pf:=hf^.odkaz_na_kontejner;
   Dispose(pf,Done);        {smaze mapu...}
   Dispose(hf,Done);        {...i vlastni data}
   end;
WFN_Font_delete:=true;
end;



Procedure Register_WFN_Loader;
begin
RegisterFontEngine('WFN',
                   @Load_WFN_font,
                   @WFN_Font_PrepChar,
                   @WFN_Font_OutText,
                   @WFN_Font_setstyle,
                   @WFN_Font_GetInfo,
                   @WFN_Font_delete);

end;




begin
Register_WFN_Loader;
end.
