unit FnFont3;
(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)
(*                                                                         *)
(*  Jednotka pro vystup textu pro vystup textu pomoci graficke knihovny    *)
(*  VenomGFX                                                               *)
(*                                                                         *)
(* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *)

{$INCLUDE defines.inc}

interface
uses Vaznik,Tedradky,VnmFnHlp;
const
   FN_OK        =    0;
   FN_LOADERROR =    1;
   FN_PRAZDNY_ZASOBNIK = 4;
   FN_FNSLRERROR = 5;

   FNFONT_VGA16 = '__VGA16';
   FNFONT_VGA14 = '__VGA14';
   FNFONT_VGA8 = '__VGA8';

   FN_FONT_VGA16:string = FNFONT_VGA16;    {proporcionalni VGA 8x16 font}
   FN_FONT_VGA16_U:string = FNFONT_VGA16;  {neproporcionalni VGA 6x16 font}

   FN_FONT_VGA14:string = FNFONT_VGA14;    {proporcionalni VGA 8x14 font}
   FN_FONT_VGA8:string = FNFONT_VGA8;     {proporcionalni VGA 8x8 font}

   MAX_ZAS_MODALITA = 2;
   MAX_ZASOBNIKU_FONTU = 20;
   MAX_ZASOBNIKU_INT = 20;
   MAX_PREDEF_FN_NAMES = 10;

   {MAX_ZASOBNIKU_BAREV = 20;
   MAX_ZASOBNIKU_POZADI = 20;}

type

{ansistring = string;}

TFont = TBitmapovyFont;
PFont = PBitmapovyFont;

TZnak = VnmFnHlp.TZnak;
PZnak = VnmFnHlp.PZnak;


FNfont3_error_type = procedure(typ,podtyp:byte;param1,param2:pointer);

  Pfnslr = ^Tfnslr;
  Tfnslr = record
  font:PFont;
  id:string[30];
  end;


PZasobnikyTagovychAtributu = ^TZasobnikyTagovychAtributu;
TZasobnikyTagovychAtributu = object
{registruje zmeny barev, pozadi a fontu tak, aby je slo obnovovat pomoci
 tagu <SF>, <SB> a <SP>}
zas_str:array[0..MAX_ZASOBNIKU_FONTU] of string[16];
zas_int:array[1..MAX_ZAS_MODALITA,0..MAX_ZASOBNIKU_INT] of longint;

{do indexu 0 se da defaultni hodnota pro odber z prazdneho zasobniku}

{zas_bar:array[0..MAX_ZASOBNIKU_BAREV] of longint;
zas_poz:array[0..MAX_ZASOBNIKU_POZADI] of longint;}

pzas_str:longint;
pzas_int:array[1..MAX_ZAS_MODALITA] of longint;

temp_pzas_str:longint;
temp_pzas_int:array[1..MAX_ZAS_MODALITA] of longint;

{pzasfont, pzasbar, pzaspoz:longint;}
vem_bylo_ok:boolean;
mxmod:longint;
mxint:longint;
Procedure Uloz_FN_promenne;
Procedure Uloz_FN_promenne_do_i0;
Procedure Vynuluj;
Procedure Vrcholy_na_i0;
Procedure Vrcholy_obnov;
Procedure VlozFont(s:string);
Procedure VlozInt(m,i:longint);
Function VemInt(m:longint):longint;

Procedure VlozBarvu(i:longint);
Procedure VlozPozadi(i:longint);
Function VemFont:string;
Function VemBarvu:longint;
Function VemPozadi:longint;
Procedure KlonujDo(var z:TZasobnikyTagovychAtributu);
Procedure KlonujZ(var z:TZasobnikyTagovychAtributu);
end;



Procedure Init_FNSLR;
Procedure Znic_FNSLR;
Function Tagy_na_Vaznik(s:pchar;delka_s:longint;f:PFont):PItRadek;


Function NajdiKritickyObrazek(const s:string):longint;
Procedure NastavVystupTextu(v:pointer);  {realne musi jit o PVirtualWindow}
Procedure ZjistiVystupTextu(var v:pointer);  {realne musi jit o PVirtualWindow}
Function Nacti_FNSLR(s:string):PFont;
Function Nacti_FNSLRV(s:string;vel:longint):PFont;
Function Najdi_ve_FNSLR(s:string):pfont;
Function FNSLR_dej_ID(f:PFont):string;

{---------------------Analog OuttextXY----------------------}
Function Print_Char(x,y:longint;znak:longint;f:PFont;barva:longint):byte;
Function Print_Char(x,y:longint;znak:longint;f:PFont;barva:longint;var w1,w2,w4:longint):byte;
{vytiskne jen jeden znak}

Procedure Print_It(x,y:longint;ss:pitradek);
Procedure Print_FN(x,y:longint;s:pchar);
Procedure Print_FN(x,y:longint;s:string);
Procedure Print_FN(x,y:longint;s:string;f:PFont);
Procedure Print_FN(x,y:longint;s:pchar;f:PFont);
Procedure Print_FNTag(x,y:longint;s:pchar;f:PFont);
Procedure Print_FNTag(x,y:longint;s:string;f:PFont);
{-----------------------------------------------------------}

Procedure FontAdr(s:string);
Function GetFontAdr:string;
function AktualniFont_FN:PFont;
function AktualniFont:string;
Function NastavAktualniFont(s:string):PFont;
Function NastavDeepSysFont(s:string):PFont;
function String2FN(s:string):PFont;
Function Je_Font_Unicode(s:string):boolean;
Procedure Znic_FN(var f:PFont);
Procedure Odpoj_FN_z_FNSLR(f:PFont);
Function Dej_odkaz_na_kontejner(f:PFont):pointer;
Function Dej_retezec_vsech_velikosti(f:PFont):string;
Function Dej_pocet_vsech_velikosti(f:PFont):longint;
Function Dej_retezec_vsech_kodovych_stranek(f:PFont):string;
Function Vyska_FN(f:PFont):longint;
Function Sirka_IT(s:pitradek):longint;
Function SirkaUseku_IT(s:PItRadek;poz,delka:longint):longint;
Function SirkaUseku_IT(s:pItradek;p:PUzel;poz,delka:longint):longint;
Function Sirka_FN(s:string;e:PFont):longint; { stejne jako "TextWidth" z unitu Graph }
Function Sirka_FN(s:pchar;e:PFont):longint;
Function Vyska_FN_aktual:byte;
Function Sirka_FN_na_Xpoz(p:pchar;font:PFont;x:longint):longint;
Function SirkaZnaku(e:PFont;znak:longint):longint;
Function SirkaBitmapyZnaku(e:PFont;znak:longint):longint;
Function VyskaBitmapyZnaku(e:PFont;znak:longint):longint;
Function SirkaEvDodatecneMezery(v:PItRadek):longint;
Function Je_bitmapa_znaku(f:pfont;znak:longint):boolean;
{Da sirku toho, co je pred kurzorem}
Procedure VyskaUsekuRadky_IT(s:PItRadek;pozice,delka:longint;var cv,hv,dv:longint);
Procedure VyskaRadky_IT(s:PItRadek;var cv,hv,dv:longint);
Procedure VyskaRadky(s:pchar;delka_s:longint;var cv,hv,dv:longint);
Procedure VyskaRadky(s:string;var cv,hv,dv:longint);
Function RychlaVyskaRadky(s:string):longint;
Function RychlaVyskaRadky_IT(s:PItRadek):longint;
Function RychlaVyskaSO(s:string):longint;
Function RychlaVyskaRadky(s:pchar):longint;
Function RychlaVyskaSO(s:pchar):longint;
Function Pozice_v_Retezci(x,xs,spx:longint;s:pchar;f:PFont):longint;
Function Pozice_v_Retezci_IT(x,xs,spx:longint;ss:PItRadek;mod_mysi:boolean):longint;
Function Zjisti_X(poz:longint;ss:PItRadek):longint;

Function OdstranTagy(s:ansistring):ansistring;

Function Jsou_def_znaky_pro_str(s:string;f:PFont):longint;
{Jsou-li definovavy vsechny znaky v retezci, vrati 0, jinak pozici prvniho
nenalezeneho znaku v retezci}
Function PocetTagu(s:ansistring):longint;
Function SmazMezery_v_tagach(t:ansistring):ansistring;

Function Dej_nty_tag(s:ansistring;n:longint):string;
Function Tag_to_FNatrb(s:string;var so,su:longint):pfnatrb;
Function NajdiTag(s:ansistring;tag:string;var separat:string):longint;

Procedure Schovej_Atributy_PIt_do_bufferu(p:pointer);
Procedure Obnov_Atributy_PIt_z_bufferu(p:pointer);

Function Predefinovany_font_pro_FNSLR(s:pointer {realne PString};f:Pfont):byte;
Function Odstran_Predefinovany_font_pro_FNSLR(s:pointer {realne PString}):byte;


const

      NORMAL     = 0;
      URCIPOLOHU = 1;
      URCIZNAK   = 2;


      FN_error:longint = FN_OK;
      FN_skut_znak:longint = 0;
      FN_pozadi:longint = -1;          {pruhlednost}

      FN_pozadi_oznaceni_zda:boolean = false; {pruhlednost}
      FN_pozadi_oznaceni_barva:longint = 658;
      FN_color:longint = 65535;
      FN_color2:longint = 65535;
      FN_COLOR_K0:word = 64000;
      FN_COLOR_K1:word = 144;
      FN_COLOR_K2:word = 61376;
      FN_podtrh:boolean = false;
      FN_inverze:boolean = false;
      FN_NEPREJIMEJ_PRVNI_ATRIBUT:boolean = false;
      FN_odlisovat_char_0:boolean = false; {pres char 0 proskrtne caru}
      FN_odlisovat_char_32:boolean = false; {do charu 32 (mezery) nakresli tecku}
      FN_vyznacovat_konec_radky:boolean = false; {na koncichradek delat kolecka}
      FN_neproporcionalni:boolean = false;  {vynuceny neproporcionalni mod i u prop. fontu}
      FN_DEBUG:boolean = false;

      FN_SIRKA_NEZNAMEHO_ZNAKU:byte = 8;
      FN_VYSKA_NEZNAMEHO_ZNAKU:byte = 8;

      FNFont3_Image_Directory:string = '';

      FN_VGA16:PFont = nil;
      FN_VGA16_u:PFont = nil;
      FN_VGA14:PFont = nil;
      FN_VGA8:PFont = nil;
      FN_default_loader_vel:byte = 16;
      FN_KONVERTUJ_NA_PROPORCIONALNI:boolean = true;

      FN_poz_v_ret_delka_radky:longint=0;
      FN_z_linky:boolean = true;  {jestli se Y souradnice u Print_FN chape}
                                  {jako poloha linky, na ktere sedi pismena}
                                  {nebo jako vrsek radky}

      FN_vector_font_size:byte = 16; {pro pouziti s CHR fonty}


var FN_selector:PVaznik;
    FN_poloha:array[0..2] of record
         x,y:longint;
         b:byte;
         n:longint;
         end;

    predef_fn:array[1..MAX_PREDEF_FN_NAMES] of PString;
    predef_fn_fn:array[1..MAX_PREDEF_FN_NAMES] of PFont;

    FNfont3_buffer_na_atributove_promenne:array[0..255] of byte;
    FNfont3_error_proc:FNfont3_error_type;

    fnf_zasobniky_def:TZasobnikyTagovychAtributu;
    fnf_zasobniky:PZasobnikyTagovychAtributu;

implementation
uses VenomMng,VenomGFX,Lacrt,Go32,Dos,GRPfile;
const
      MAXFONT = 35;

      {fnmagic:pchar='ëmÕonç ';
      unimagic:pchar='öaö';}
      ak_Y:longint = 0;
      max_Y:longint = 479;
      vrchol_zf:byte = 0;
      vrchol_zb:byte = 0;
      vrchol_zp:byte = 0;

      FN_default:string[30] = FNFONT_VGA16;   { proporcionalni VGA font }
      FN_syst_font:string[30] = FNFONT_VGA16;
      Fn_default_fn:PFont = nil;

var fnf_target:PVirtualwindow;


Procedure NastavVystupTextu(v:pointer); {V je ukazatel na VirtualWindow}
begin
fnf_target:=v;
end;

Procedure ZjistiVystupTextu(var v:pointer); {V je ukazatel na VirtualWindow}
begin
v:=fnf_target;
end;


Function Predefinovany_font_pro_FNSLR(s:pointer {realne PString};f:Pfont):byte;
var a:byte;
begin
for a:=4 to MAX_PREDEF_FN_NAMES do
    if predef_fn[a]=nil then
       begin
       predef_fn[a]:=pstring(s);
       predef_fn_fn[a]:=f;
       Exit(a);
       end;
Predefinovany_font_pro_FNSLR:=0;
end;


Function Odstran_Predefinovany_font_pro_FNSLR(s:pointer {realne PString}):byte;
var a,b:byte;
begin
for a:=4 to MAX_PREDEF_FN_NAMES do
    if predef_fn[a]=nil then Exit(0)
       else
       if predef_fn[a]=pstring(s) then
          begin
          for b:=a to MAX_PREDEF_FN_NAMES-1 do
              begin
              predef_fn[b]:=predef_fn[b+1];
              predef_fn_fn[b]:=predef_fn_fn[b+1];
              end;
          predef_fn[MAX_PREDEF_FN_NAMES]:=nil;
          predef_fn_fn[MAX_PREDEF_FN_NAMES]:=nil;
          Exit(a);
          end;

Odstran_Predefinovany_font_pro_FNSLR:=0;
end;




Function HeapPChar(s:string):pchar;
var p:pchar;
    n:byte;
begin
n:=Length(s);
if n=0 then Exit(nil);
GetMem(p,n+1);
Move(s[1],p^,n);
p[n]:=#0;
HeapPChar:=p;
end;


Procedure TZasobnikyTagovychAtributu.Uloz_FN_promenne;
begin
VlozFont(AktualniFont);
VlozBarvu(FN_color);
VlozPozadi(FN_pozadi);
end;


Procedure TZasobnikyTagovychAtributu.Uloz_FN_promenne_do_i0;
begin
Vrcholy_na_i0;
Uloz_FN_promenne;
Vrcholy_Obnov;
end;



Procedure TZasobnikyTagovychAtributu.Vynuluj;
var a:byte;
begin
vem_bylo_ok:=true;
mxmod:=MAX_ZAS_MODALITA;
mxint:=MAX_ZASOBNIKU_INT;
pzas_str:=0;
zas_str[0]:='';          {defaultni hodnota pro index 0}
for a:=1 to mxmod do
    begin
    pzas_int[a]:=0;
    zas_int[a,0]:=0;     {defaultni hodnota pro index 0}
    end;
end;


Procedure TZasobnikyTagovychAtributu.Vrcholy_na_i0;
var i:byte;
begin
temp_pzas_str:=pzas_str;
pzas_str:=-1;
for i:=1 to mxmod do
    begin
    temp_pzas_int[i]:=pzas_int[i];
    pzas_int[i]:=-1;
    end;
end;


Procedure TZasobnikyTagovychAtributu.Vrcholy_obnov;
var i:byte;
begin
pzas_str:=temp_pzas_str;
for i:=1 to mxmod do
    pzas_int[i]:=temp_pzas_int[i];
end;


Procedure TZasobnikyTagovychAtributu.VlozInt(m,i:longint);
begin
if pzas_int[m]<mxint then
   begin
   inc(pzas_int[m]);
   zas_int[m,pzas_int[m]]:=i;
   end;
end;


Function TZasobnikyTagovychAtributu.VemInt(m:longint):longint;
begin
vem_bylo_ok:=false;
if pzas_int[m]<1
   then VemInt:=zas_int[m,0]       {na indexu 0 bude defaultni hodnota}
   else begin
   vem_bylo_ok:=true;
   VemInt:=zas_int[m,pzas_int[m]];
   dec(pzas_int[m]);
   end;
end;


Procedure TZasobnikyTagovychAtributu.VlozFont(s:string);
begin
if pzas_str<MAX_ZASOBNIKU_FONTU then
   begin
   inc(pzas_str);
   zas_str[pzas_str]:=s;
   end;
end;


Procedure TZasobnikyTagovychAtributu.VlozBarvu(i:longint);
begin
VlozInt(1,i);
end;


Procedure TZasobnikyTagovychAtributu.VlozPozadi(i:longint);
begin
VlozInt(2,i);
end;


Function TZasobnikyTagovychAtributu.VemFont:string;
begin
vem_bylo_ok:=false;
if pzas_str<1
   then VemFont:=zas_str[0]       {na indexu 0 bude defaultni hodnota}
   else begin
   vem_bylo_ok:=true;
   VemFont:=zas_str[pzas_str];
   dec(pzas_str);
   end;
end;


Function TZasobnikyTagovychAtributu.VemBarvu:longint;
begin
VemBarvu:=VemInt(1);
end;


Function TZasobnikyTagovychAtributu.VemPozadi:longint;
begin
VemPozadi:=VemInt(2);
end;


Procedure TZasobnikyTagovychAtributu.KlonujDo(var z:TZasobnikyTagovychAtributu);
var i,j:longint;
begin
z.pzas_str:=pzas_str;

z.mxmod:=mxmod;
z.mxint:=mxint;

for i:=1 to mxmod do z.pzas_int[i]:=pzas_int[i];

for i:=0 to pzas_str do
    z.zas_str[i]:=zas_str[i];


for j:=1 to mxmod do
    for i:=0 to mxint do
        z.zas_int[j,i]:=zas_int[j,i];
end;


Procedure TZasobnikyTagovychAtributu.KlonujZ(var z:TZasobnikyTagovychAtributu);
var i:longint;
begin

z.KlonujDo(self);

{
pzasfont:=z.pzasfont;
pzasbar:=z.pzasbar;
pzaspoz:=z.pzaspoz;

for i:=1 to z.pzasfont do
    zas_font[i]:=z.zas_font[i];

for i:=1 to z.pzasbar do
    zas_bar[i]:=z.zas_bar[i];

for i:=1 to z.pzaspoz do
    zas_poz[i]:=z.zas_poz[i];
}
end;


Procedure FNfont3_error_default(typ,podtyp:byte;param1,param2:pointer);
begin
{dummy}
end;



Procedure Expand(a:byte;p:pointer);
var b:byte;
    q:^boolean;
begin
q:=p;
inc(q,7);
for b:=0 to 7 do
    begin
    q^:=odd(a);
    a:=a shr 1;
    dec(q);
    end;
end;



Function NormalizujJmenoSouboru(s:string):string;
begin
if Pos('\',s)=0 then NormalizujJmenoSouboru:=ADRESAR_S_FONTY+s
              else NormalizujJmenoSouboru:=s;
end;


Procedure Nacti_FN(rez:string;var f:PFont);
var p:pointer;
    ff:PFont;
begin
ff:=Nacti_FNSLR(rez);
if FN_error=FN_OK then f:=ff else f:=nil;
end;



Procedure Znic_FN(var f:PFont);
var o:pointer;
    a:longint;

begin
o:=f^.rukojet;
a:=Venom_mng_GetFontPtrSlot(o);
if a>0 then
   begin
   Venom_mng_kill_font_internal2({'',}a,0);
   f:=nil;
   end;
end;


Procedure Odpoj_FN_z_FNSLR(f:PFont);
var o:pointer;
    a:longint;
    h:PObecnyFont;

begin
o:=f^.rukojet;
a:=Venom_mng_GetFontPtrSlot(o);
if a>0 then
   begin
   h:=f^.rukojet;   {Odpojeni: Nactu zastresujici PObecnyFont...}
   h^.fdata:=nil;   {...a tam smazu spojeni s <F>}
   Venom_mng_kill_font_internal2({'',}a,0);  {Smazeme zastresujici struktury,}
                                             {ale na <F> samotne to nedosahne}
   f^.rukojet:=nil; {a na zastreseni zneplatnime odkaz}
   end;
end;


Function Dej_odkaz_na_kontejner(f:PFont):pointer;
var h:PObecnyFont;
begin
h:=f^.rukojet;
if h=nil then Exit(nil);
Dej_odkaz_na_kontejner:=h^.odkaz_na_kontejner;
end;


Function Dej_retezec_vsech_velikosti(f:PFont):string;
var o:PObecnyFont;
    a,b:longint;
    s:string;

begin
b:=Venom_mng_GetActFontSlot;
o:=f^.rukojet;
a:=Venom_mng_GetFontPtrSlot(o);
Venom_mng_SetActFontSlot(a);
s:=GetPossibleTextSizes;
Venom_mng_SetActFontSlot(b);
Dej_retezec_vsech_velikosti:=s;
end;


Function Dej_pocet_vsech_velikosti(f:PFont):longint;
var s:string;
    i:longint;
begin
s:=Dej_retezec_vsech_velikosti(f);
if s='' then Exit(0);
if s='-1' then Exit(-1);     {odpoved pro vektorove fonty}
i:=Hmasis(s,',');
Dej_pocet_vsech_velikosti:=i+1;
end;


Function Dej_retezec_vsech_kodovych_stranek(f:PFont):string;
var o:PObecnyFont;
    a,b:longint;
    s:string;

begin
b:=Venom_mng_GetActFontSlot;
o:=f^.rukojet;
a:=Venom_mng_GetFontPtrSlot(o);
Venom_mng_SetActFontSlot(a);
s:=GetPossibleTextCodepages;
Venom_mng_SetActFontSlot(b);
Dej_retezec_vsech_kodovych_stranek:=s;
end;


function String2FN(s:string):PFont;
var v:pfont;
begin
v:=Nacti_FNSLR(s);
String2FN:=v;
end;


Function Je_Font_Unicode(s:string):boolean;
var f:pfont;
begin
f:=String2FN(s);
if f=nil then Je_Font_Unicode:=false
   else Je_Font_Unicode:=f^.unicode;
end;


Function AktualniFont:string;
begin
AktualniFont:=FN_default;
end;


Function AktualniFont_FN:PFont;
begin
AktualniFont_FN:=fn_default_fn;
end;


Function NastavAktualniFont(s:string):PFont;
var b:byte;
    f:PFont;
begin
f:=Nacti_FNSLR(s);
if f<>nil then
   begin
   FN_default:=s;
   FN_default_fn:=f;
   end;
NastavAktualniFont:=FN_default_fn;
end;


Function NastavDeepSysFont(s:string):PFont;
var f,g:PFont;
begin
f:=Nacti_FNSLR(s);
if f<>nil then
   begin
   FN_syst_font:=s;
   NastavDeepSysFont:=f;
   end
   else NastavDeepSysFont:=nil;
end;


Function IzolujSlovo_z_Tagu(s:string;b:byte):string;
const oddelovace:set of char = [';','>',#13,#10];
var a,c,d:byte;
    t:string;
begin
a:=b;
c:=b;
d:=Length(s)+1;
while (a>0) and (not (s[a] in oddelovace)) do dec(a);
while (c<d) and (not (s[c] in oddelovace)) do inc(c);
t:=Copy(s,a+1,c-a-1);
IzolujSlovo_z_Tagu:=t;
end;

Function Vysekni_Tag(ss:pchar;l,ds:longint;var delka:longint):string;
{do DS nekdy davam maxlongint}
var m:longint;
    t:string;
    oc:char;

begin
if l>ds then
   begin delka:=0;Exit('');end;

if (ss[l-1]='>') then
   begin delka:=1;Exit('');end;

if (ss[l-1]<>'<') then
   begin delka:=0;Exit('');end;

if (l=ds) then   {potencialni bug. Kdyz je < poslednim znakem retezce}
   begin delka:=0;Exit('');end;

if (ss[l]='<') then begin
   delka:=1;Exit('');
   end;

m:=PSearchLim(ss,'>',l,ds);

if m=0 then          { neuzavreny tag? }
   m:=PSearch_error; { v tom pripade by v teto promenne mel byt konec retezce}

delka:=m-l+1;
t[0]:=char(delka);
Move(ss[l-1],t[1],delka);   {Tag je vyseknuty do T}
dec(delka);
t:=Convert_Up(SkipAllSpaces(t));
Vysekni_Tag:=t;
end;

Procedure Vyska_ze_Selektoru(s:string;var cv,hv,dv:longint);
var c,p:longint;
    f:PFont;
begin
f:=Nacti_FNSLR(s);  { nacist do selectoru }
p:=Vyska_FN(f);     { pripadne prohozeni }
if p>cv then cv:=p;
p:=f^.so;
if p>hv then hv:=p;
p:=f^.su;
if p>dv then dv:=p;
end;

Procedure VyskaUsekuRadky_IT(s:PItRadek;pozice,delka:longint;var cv,hv,dv:longint);
var f:PFont;
    v:Pfnatrb;
    n:longint;
begin
if s^.aa=nil then
   begin
   hv:=fn_default_fn^.so;
   dv:=fn_default_fn^.su;
   cv:=hv+dv;
   Exit;
   end;
hv:=0;
dv:=0;
if delka=0 then delka:=1;   {ochrana pred prazdnymi retezci}
n:=pozice+delka-1;
s^.aa^.Reset;
while not s^.aa^.Konec do
   begin
   v:=s^.aa^.Nacti;
   f:=v^.font;
   if v^.pozice>n then Break;
   if v^.pozice<pozice then
      begin
      hv:=f^.so;
      dv:=f^.su;
      end
      else begin
      if f^.so>hv then hv:=f^.so;
      if f^.su>dv then dv:=f^.su;
      end;
   end;
cv:=hv+dv;
end;

Procedure VyskaRadky_IT(s:PItRadek;var cv,hv,dv:longint);
begin
VyskaUsekuRadky_IT(s,1,s^.up,cv,hv,dv);
end;

Procedure VyskaRadky(s:pchar;delka_s:longint;var cv,hv,dv:longint);
var v:PItRadek;
    f:pfont;

begin
if (s=nil) or (s[0]=#0) or (s[1]=#0) then
   begin
   f:=aktualnifont_fn;
   hv:=f^.so;
   dv:=f^.su;
   cv:=hv+dv;
   end
   else begin
   {UlozZasobniky;}
   {if debuglevel>10 then debuglevel:=debuglevel+50;}
   v:=Tagy_na_vaznik(s,delka_s,nil);
   {if debuglevel>50 then debuglevel:=debuglevel-50;}
   {ObnovZasobniky;}
   VyskaRadky_IT(v,cv,hv,dv);
   Dispose(v,Done);
   end;
end;

Procedure VyskaRadky(s:string;var cv,hv,dv:longint);
begin
s:=s+#0;
VyskaRadky(@s[1],Length(s),cv,hv,dv);
end;

Function RychlaVyskaRadky(s:pchar):longint;
var cv,hv,dv:longint;
begin
VyskaRadky(s,cv,hv,dv);
RychlavyskaRadky:=cv;
end;

Function RychlaVyskaRadky_IT(s:PItRadek):longint;
var cv,hv,dv:longint;
begin
RychlaVyskaRadky_IT:=s^.so+s^.su;
end;

Function RychlaVyskaSO(s:pchar):longint;
var cv,hv,dv:longint;
begin
VyskaRadky(s,cv,hv,dv);
RychlavyskaSO:=hv;
end;

Function RychlaVyskaRadky(s:string):longint;
begin
s:=s+#0;
RychlaVyskaRadky:=RychlaVyskaRadky(@s[1]);
end;

Function RychlaVyskaSO(s:string):longint;
var p:pchar;
begin
s:=s+#0;
p:=@s[1];
RychlaVyskaSO:=RychlaVyskaSO(p);
end;

Procedure Zatemni_FN(x1,y1,x2,y2:longint);
begin
if FN_pozadi_oznaceni_zda=true
   then Bar(fnf_target^,x1,y1,x2,y2,FN_pozadi_oznaceni_barva) else

if FN_pozadi>-1
   then Bar(fnf_target^,x1,y1,x2,y2,FN_pozadi);
end;

Procedure Podtrhni_FN(x1,x2,y:longint);
begin
if FN_podtrh then LineHorz(fnf_target^,x1,x2,y,FN_color);
end;

Procedure Prechod_na_novy_font(s:string);
var v:pfnslr;
    f:PFont;
begin
fnf_zasobniky^.VlozFont(fn_default);
f:=Nacti_FNSLR(s);
FN_default:=s;
FN_default_fn:=f;
end;

Procedure Prechod_na_stary_font;
var s:string;
    a:longint;
    f:pfont;

begin
s:=fnf_zasobniky^.VemFont;
if fn_error=FN_OK then
   begin
   f:=Najdi_ve_FNSLR(s);
   if f<>nil then
      begin
      FN_default_fn:=f;
      FN_default:=s;
      end;
   end;
end;

Procedure Prechod_na_novou_barvu(s:string);
begin
fnf_zasobniky^.VlozBarvu(FN_color);
{if s='!' then FN_color:=FN_color2 else FN_color:=MyVal(s);}
if s='!' then FN_color:=FN_color or $10000   {nastavim 16.bit}
         else FN_color:=MyVal(s);
end;

Procedure Prechod_na_starou_barvu;
var w:word;
begin
w:=fnf_zasobniky^.VemBarvu;
FN_color:=w;
end;

Procedure Prechod_na_nove_pozadi(s:string);
begin
fnf_zasobniky^.VlozPozadi(FN_pozadi);
if s[1]='-' then FN_pozadi:=-1 else
   FN_pozadi:=MyVal(s);
end;

Procedure Prechod_na_stare_pozadi;
var l:longint;
begin
l:=fnf_zasobniky^.VemPozadi;
FN_pozadi:=l;
end;

Procedure Zmen_Podtrzeni(s:string);
begin
if s[1]='+' then FN_podtrh:=true else
if s[1]='-' then FN_podtrh:=false;
end;



Procedure Skok_na_novou_pozici(t:string;var x,y:longint);
var a,b:byte;
    s:string;
    r:real;
begin
a:=Pos(',',t);
s:=Copy(t,1,a-1);
delete(t,1,a);
{v S mame X-souradnici, v T Y-souradnici}
b:=Pos('%',s);       {Jdeme resit Xovou souradnici}
if b=0 then x:=MyVal(s) else
   begin
   r:=MyVal(Copy(s,1,b-1))/100*fnf_target^.breite-1;
   if s[b+1]='+' then r:=r+MyVal(Copy(s,b+2,255)) else
   if s[b+1]='-' then r:=r-MyVal(Copy(s,b+2,255));
   x:=round(r);
   end;

b:=Pos('%',t);       {Jdeme resit Yovou souradnici}
if b=0 then y:=MyVal(t) else
   begin
   r:=MyVal(Copy(t,1,b-1))/100*fnf_target^.hoehe-1;
   if t[b+1]='+' then r:=r+MyVal(Copy(t,b+2,255)) else
   if t[b+1]='-' then r:=r-MyVal(Copy(t,b+2,255));
   y:=round(r);
   end;
end;



Function Nacti_Obrazek(var s:string;var yr:longint):boolean;
var a,b,xp,yp:longint;
    barpr:longint;
    prac,prac2:string;
    v:PVirtualWindow;

begin
s:=SkipAllSpaces(s);
delete(s,1,4);
barpr:=0;
a:=Pos('(',s);
b:=Pos(')',s);
if b>a then
   begin
   if s[a+1]='-' then barpr:=-1 else barpr:=MyVal(Copy(s,a+1,b-a));
   delete(s,a,b-a+1);
   end;

a:=Pos(':',s);       { budeme obrazek polohovat?}
if a=0 then {ne?}
   begin
   prac:=s;
   xp:=0;
   yp:=0;
   end else {jo?}
   begin
   prac:=Copy(s,1,a-1);
   delete(s,1,a);
   a:=Pos(',',s);
   if a=0 then
      begin
      xp:=MyVal(s);
      yp:=0;
      end
      else
      begin
      xp:=MyVal(Copy(s,1,a-1));
      yp:=MyVal(Copy(s,a+1,Length(s)));
      end;
   end;

New(v);

if prac[Length(prac)]='"' then delete(prac,Length(prac),1);
if prac[1]='"' then delete(prac,1,1);

{prac2:=Convert_UP(StripExt(prac));}

b:=Venom_mng_Get_Image_Loader_Index(prac);
if b<>0 then a:=Load_Image(FNFont3_Image_Directory+prac,v^);

if a=LI_ok then
   begin
   s:='IMX='+MyStr(longint(v))+','+MyStr(xp)+'#'+MyStr(yp)+':'+MyStr(barpr);
   yr:=v^.hoehe;
   Nacti_Obrazek:=true;
   end
   else begin
   s:='';
   yr:=0;
   Nacti_Obrazek:=false;
   end;
end;


Function VytahniObrazek(const s:string;var a:longint;var v:PVirtualwindow;var xr,yr,xp,yp,clr:longint):boolean;
var b,c,d,e:longint;
begin
a:=Search(s,'IMX=',a);        {A je v nem obrazek?}
if a=0 then Exit(false);

b:=Search(s,',',a+4);          {V}
c:=Search(s,'#',b+1);         {XP}
d:=Search(s,':',c+1);         {YP}

e:=Search(s,';',a);
if e=0 then e:=Length(s)+1;   {CLR}

v:=pointer(MyVal(Mid(s,a+4,b-1)));   {V}
xp:=MyVal(Mid(s,b+1,c-1));           {XP}
yp:=MyVal(Mid(s,c+1,d-1));           {YP}
clr:=MyVal(Mid(s,d+1,e-1));          {CLR}

xr:=v^.breite;
yr:=v^.hoehe;

a:=e;
VytahniObrazek:=true;
end;



Procedure Zobraz_Obrazek(const s:string;x,y:longint);
var v:PVirtualwindow;
    a,b,c,xr,yr,xp,yp:longint;
    barpr:longint;

begin
a:=1;
VytahniObrazek(s,a,v,xr,yr,xp,yp,barpr);
if barpr>=0 then PutClippedHCSprite(fnf_target^,v^,x+xp,y+yp,barpr) else
                 PutClippedSprite(fnf_target^,v^,x+xp,y+yp);

end;

Procedure DesifrujVysku(s:string;var so,su:longint);
var i:byte;
begin
so:=-1;
su:=-1;
i:=Pos(',',s);
case i of
   0:so:=MyVal(s);
   1:su:=MyVal(Copy(s,2,255));
   else begin
   so:=MyVal(Copy(s,1,i-1));
   su:=MyVal(Copy(s,i+1,255));
   end;
end;
end;

Procedure Zpracuj_Tag1(t:string;var so,su:longint;var u:string);
{Vola se v pripravne fazi pri konverzi tagu na atributove uzly}
var v,w:string;
    delka2,yr:longint;
begin
u:='';
so:=-1;
su:=-1;
if t='' then Exit;                {prazdny tag?}
if t[Length(t)]<>'>' then Exit;   {neuzavreny tag?}
delete(t,1,1);
repeat
v:=IzolujSlovo_z_Tagu(t,1);
delka2:=Length(v)+1;
delete(t,1,delka2);

{ihned se zpracuji tagy urcujici atributy textu (barva, font, pozadi...)}
if Copy(v,1,5)='FONT=' then        { ZMENA FONTU }
   Prechod_na_novy_font(Copy(v,6,delka2))
   else

if Copy(v,1,2)='SF' then           { FONT PREDTIM }
   Prechod_na_stary_font
   else

if Copy(v,1,6)='BARVA=' then       { ZMENA BARVY }
   Prechod_na_novou_barvu(Copy(v,7,delka2))
   else

if Copy(v,1,7)='POZADI=' then      { ZMENA POZADI }
   Prechod_na_nove_pozadi(Copy(v,8,delka2))
   else

if Copy(v,1,7)='PODTRH=' then
   Zmen_Podtrzeni(Copy(v,8,delka2)) { PODTRZENI TEXTU }
   else

if Copy(v,1,2)='SP' then           { POZADI PREDTIM }
   Prechod_na_stare_pozadi
   else

if Copy(v,1,2)='SB' then           { BARVA PREDTIM }
   Prechod_na_starou_barvu
   else

if Copy(v,1,6)='VYSKA=' then
   DesifrujVysku(Copy(v,7,delka2),so,su)
   else

   begin
   {nasledujici tagy uz nemaji charakter atributu textu - jso to jednorazove}
   {elementy typu obrazek. Ty nebudou zpracovany hned, ale az primo behem psani}

   if Copy(v,1,4)='IMG=' then {Pokud jde o obrazek, tak se na to podivame}
      begin                   {pozorneji}
      Nacti_Obrazek(v,yr); {Zkusime ho nacist (pri tom se muze zmenit V)}
      if yr<>0 then        {Jestlize byl uspesne nacten tak}
         begin
         if u<>'' then u:=u+';';
         u:=u+v;                  {pripiseme upraveny tag do extratagu}
         end;
      end
      else begin
      if u<>'' then u:=u+';';
      u:=u+v;
      end;
   end;
until Length(t)<2;     { Mozna by stacilo "...=0" }
end;


Procedure Zpracuj_Tag2(t:string;var x,y:longint);
{Zpracovani extra tagu, nemajicich charakter atributu textu. Volano procedurou
 Print_IT}
var v:string;
    delka2:longint;
begin
repeat
v:=IzolujSlovo_z_Tagu(t,1);
delka2:=Length(v)+1;
delete(t,1,delka2);
if Copy(v,1,4)='IMX=' then         { ZOBRAZI OBRAZEK }
   Zobraz_Obrazek(v,x,y)
   else


if Copy(v,1,5)='SKOK=' then        { PRESUN GRAFICKEHO KURZORU}
   Skok_na_novou_pozici(Copy(v,6,delka2),x,y)
   else
   ;

until Length(t)<1;
end;





Function NajdiKritickyObrazek(const s:string):longint;
var v:PVirtualwindow;
    a,y,yy,xr,yr,xp,yp:longint;
    barpr:longint;
    n:boolean;

begin
a:=1;
y:=0;

repeat
n:=VytahniObrazek(s,a,v,xr,yr,xp,yp,barpr);
if N then
   begin
   yy:=yr+yp;
   if yy>y then y:=yy;
   end;
until not N;

NajdiKritickyObrazek:=y;
end;


Procedure Schovej_Atributy_PIt_do_bufferu(p:pointer);
var q:pchar;
begin
q:=p;
Longint2pointer(FN_color,@q[0]);
Longint2pointer(FN_pozadi,@q[4]);
Byte2pointer(byte(FN_podtrh),@q[8]);
Byte2pointer(byte(FN_pozadi_oznaceni_zda),@q[9]);
Byte2pointer(byte(FN_inverze),@q[10]);
Byte2pointer(byte(FN_neproporcionalni),@q[11]);
Longint2pointer(longint(FN_default_fn),@q[12]);
Move(FN_default[0],q[16],Length(FN_default)+1);
end;


Procedure Obnov_Atributy_PIt_z_bufferu(p:pointer);
var q:pchar;
begin
q:=p;
FN_color:=Pointer2Longint(@q[0]);
FN_pozadi:=Pointer2Longint(@q[4]);
FN_podtrh:=boolean(Pointer2Byte(@q[8]));
FN_pozadi_oznaceni_zda:=boolean(Pointer2Byte(@q[9]));
FN_inverze:=boolean(Pointer2Byte(@q[10]));
FN_neproporcionalni:=boolean(Pointer2Byte(@q[11]));
FN_default_fn:=pointer(Pointer2Longint(@q[12]));
Move(q[16],FN_default[0],byte(q[16])+1);
end;


Procedure NastavAtributy(v:Pfnatrb;jen_extra:boolean;var x,y:longint;var ff_:PFont);
var s:string;
begin
if jen_extra=false then
   begin
   FN_color:=v^.barva;
   if (FN_color and $10000)<>0   {nastaven 16. bit?...}
      then FN_color:=FN_color2;  {...tak to vem barvu odjinud}
   ff_:=v^.font;
   s:=FNSLR_dej_ID(ff_);
   if s<>'' then FN_default:=s;
   FN_pozadi:=v^.pozadi;
   FN_podtrh:=(v^.modifikace and 1)<>0;
   FN_pozadi_oznaceni_zda:=(v^.modifikace and 2)<>0;
   FN_inverze:=(v^.modifikace and 4)<>0;
   FN_neproporcionalni:=(v^.modifikace and (64+32))<>0;
   end;
if v^.extra<>nil then
   begin
   {if FN_DEBUG then writeln(v^.extra^);}
   Zpracuj_Tag2(v^.extra^,x,y);
   end;
end;

Function NeznamyZnak(f:PFont;x,y:longint):longint;
var dx,dy:longint;
begin
if (f=nil) then
   begin
   dx:=FN_SIRKA_NEZNAMEHO_ZNAKU;
   dy:=FN_VYSKA_NEZNAMEHO_ZNAKU;
   end
   else begin
   dx:=SirkaBitmapyZnaku(f,79);  {rozmery ramecku vezmeme podle znaku "O"}
   dy:=VyskaBitmapyZnaku(f,79);
   end;

LineClipped(fnf_target^,x,y,x+dx,y,36960);
LineClipped(fnf_target^,x,y+dy,x+dx,y+dy,36960);
LineClipped(fnf_target^,x,y,x,y+dy,36960);
LineClipped(fnf_target^,x+dx,y,x+dx,y+dy,36960);
NeznamyZnak:=7;
end;





Function Zvyrazni_char_0(f:PFont;x,y,posun:longint):longint;
var dx,dy:longint;
begin
if (f=nil) then
   begin
   dy:=FN_VYSKA_NEZNAMEHO_ZNAKU;
   end
   else begin
   dy:=VyskaBitmapyZnaku(f,0);  {zkusime podle znaku 0, pripadne jako fallback...}
   end;                         {...pouzije znak "O"}

dx:=posun div 2;
Circle(fnf_target^,x+dx-1,y+dy div 2,dx,36960);
Zvyrazni_char_0:=7;
end;


Procedure ZvyrazniMezeru(x1,x2,y1,y2,barva:longint);
begin
PutClippedPixel(fnf_target^,(x1+x2) div 2, (y1+y2) div 2+1,barva);
end;


Function Tag_to_FNatrb(s:string;var so,su:longint):pfnatrb;
var f:pfnatrb;
    t:string;
begin
t:='';
if s<>'' then
   begin
   s:=Convert_up(s);
   Zpracuj_Tag1(s,so,su,t);
   end;
f:=New(Pfnatrb,Init);
f^.DefaultA;
if t<>'' then
   f^.extra:=NaPstring(t);
Tag_to_FNatrb:=f;
end;



Function Print_Char(x,y:longint;znak:longint;f:PFont;barva:longint;var w1,w2,w4:longint):byte;
{Dulezite - polohu Y chape jako linku, na ktere sedi pismena.}
var bb:^byte;
    mimo:byte;
    z,wx1,wy1,wx2,wy2:longint;
    sbitmapy,vbitmapy,myzdp,mykorx_np:longint;
    MyZ,MyZnak:PZnak;
    je_nouzovy_znak:boolean;

begin

{Definujeme zastupny znak Z, ktery poresi pripady nedefinovanych znaku}
if f^.unicode=false
   then if znak>255 then z:=32 else z:=znak
   else begin      {t.j. unicode=true}
   if je_bitmapa_znaku(f,znak)=false then z:=32 else z:=znak;
   if (z<32) and (FN_odlisovat_char_0=true) then z:=32;
      {unicode fonty by nemely obsahovat znaky pro kody pod 32}
   end;

{}{debug}if znak=32 then
          z:=z;

MyZnak:=f^.PrepChar(znak);
MyZ:=f^.PrepChar(z);

if myZ=nil then
   begin
   {je_nouzovy_znak:=true;
   myZ:=New(PZnak(Init));
   myZ.relX:=0;}
   w1:=x;
   w2:=y-FN_VYSKA_NEZNAMEHO_ZNAKU;
   w4:=SirkaZnaku(f,znak);      {o kolik po vykresleni znaku posuneme X}
   bb:=nil;
   end
   else begin

   {je_nouzovy_znak:=false;}
   w1:=MyZ^.relX+x;         {kde zahajit kresleni bitmapy - X}
   if FN_neproporcionalni
      then begin
      mykorX_np:=MyZ^.korX_np;
      if mykorX_np<>-128 then inc(w1,mykorX_np);
      end;
   w2:=MyZ^.relY+y;         {kde zahajit kresleni bitmapy - Y}
   w4:=SirkaZnaku(f,znak);      {o kolik po vykresleni znaku posuneme X}
   end;

if (z=znak) and (myznak<>nil) then bb:=MyZnak^.data else bb:=nil;

sbitmapy:=SirkaBitmapyZnaku(f,znak);
vbitmapy:=VyskaBitmapyZnaku(f,znak);


wx1:=x;
wy1:=y-f^.so;
wx2:=w1+w4-1;
wy2:=y+f^.su-1;

Zatemni_FN(wx1,wy1,wx2,wy2+1);  {vyrid prosvecovani pozadi}
                                {(to +1 je tam proto, ze chceme prosvitit i}
                                { jeden scanradek pod textem)}
Podtrhni_FN(wx1,wx2,y+1);

if (myZ<>nil) {and (nouzovy_znak=false)} then myzdp:=MyZ^.dp else myzdp:=0;

mimo:=PutChar_FN(fnf_target^,bb,w1,w2,
                               sbitmapy,
                               vbitmapy,
                               myzdp,
                               barva);
{PutChar_FN se vola i pro nedefinovane znaky, a to z duvodu clippingu.
 (neni potreba se bat, nesnazi se vykreslovat pixely z neex. bitmapy)}

if znak=0 then
   if FN_odlisovat_char_0=true then Zvyrazni_char_0(f,w1,w2,sbitmapy)
   else else {t.j. z<>0}
   begin
   if bb=nil
      then if (znak<>32) then NeznamyZnak(f,w1,w2);
      {mezera nekdy nema fontech prirazenou bitmapu
       (rozmery ale definovane jsou)}

   if (znak=32) and (FN_odlisovat_char_32=true) then ZvyrazniMezeru(wx1,wx2,wy1,y,barva);
   end;
if FN_inverze then Inversion(fnf_target^,wx1,wy1,wx2,wy2);
                   {Bar(target^,wx1,wy1,wx2,wy2,55);}


Print_Char:=mimo;
end;


Function Print_Char(x,y:longint;znak:longint;f:PFont;barva:longint):byte;
var w1,w2,w4:longint;
begin
Print_Char:=Print_Char(x,y,znak,f,barva,w1,w2,w4);
end;



Procedure Print_It(x,y:longint;ss:PItRadek);
Label Preskok;
var a,b,d,znak,mimo:longint;
    w1,w2,w3,w4,xr:longint;
    fnp,konec_psani:boolean;
    q:PUzel;
    vv:Pfnatrb;
    ap:byte;
    mm,jex:boolean;
    s:pchar;
    bb:^byte;
     f:PFont;
    _odz,_doz,_posunv,_posunm:longint;
    buffer_na_atributove_promenne:array[0..255] of byte;


begin
{DEBUG --- if ss^.delka>20 then bar(vga,0,560,799,599,0);}
s:=ss^.p;
if ss^.aa=nil then begin q:=nil;vv:=nil;f:=fn_default_fn;end
   else begin
   q:=ss^.aa^.first;
   vv:=q^.vazba;
   f:=vv^.font;       {zacneme psat s timto fontem}
   end;


mimo:=-1;             {to znamena, ze dosud nebylo nic vypsano}
xr:=x;                {v pripade CRLF musi vedet, kam se vratit}
a:=1;                 {na zacatek retezce}
konec_psani:=false;

{if fn_z_linky=false then inc(y,ss^.so);}
if fn_z_linky=false then inc(y,f^.so);

fnp:=false;
for b:=0 to 2 do
    if (FN_poloha[b].B=URCIZNAK) then
       begin
       if (FN_poloha[b].N=1) then
          begin
          FN_poloha[b].x:=x;
          FN_poloha[b].y:=y;
          FN_poloha[b].b:=NORMAL;
          end else fnp:=true;
       end;

Schovej_Atributy_PIt_do_bufferu(@buffer_na_atributove_promenne);
_odz:=0;_doz:=0;_posunv:=0;_posunm:=0;
{============================================================================}
repeat
if q<>nil then
   if a=vv^.pozice then  {meni se na teto pozici atribut textu?}
      begin
      if FN_DEBUG then
         begin
         if f^.unicode
            then LineVert(fnf_target^,x,y-15,y+10,64040)
            else LineVert(fnf_target^,x,y-15,y+10,64060);
         end;
      jex:=((a=1) and (FN_NEPREJIMEJ_PRVNI_ATRIBUT=true));
      NastavAtributy(vv,jex,x,y,f);  {tak ho tedy zmen}
      q:=q^.dalsi;         {a o ted se zajimej o pristi zmenu}
      if q<>nil then vv:=q^.vazba else vv:=nil;
      end;

{debug}{if (f^.so>30) or (f^.su>30) then
          b:=b;}


{~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~}
if ss^.up=0 then Goto Preskok;

if (ss^.Znak(a)=13) and (a<ss^.up-1) and (ss^.Znak(a+1)=10) then
{----------------------------------------------------------------------------}
   begin        {CRLF?, prechod na dalsi radek?}
   x:=xr;y:=y+f^.sosu;
   inc(a);
   end
{----------------------------------------------------------------------------}

   else begin
   znak:=ss^.Znak(a);
   mimo:=Print_Char(x,y,znak,f,FN_color,w1,w2,w4);

   case mimo of
      0:{kompletne vypsany znak}
        begin
        if _odz=0 then _odz:=a;           {prvni kompletne vypsany znak}
        _doz:=a;                          {posledni kompletne vypsany znak}
        end;

      1:{uplne moc vpravo}
        begin
        ss^.lch:=znak;
        _posunv:=w4;       {zapamatuj si sirku prvniho nevypsaneho,}
                           {at vime, o kolik potom}
                           {posunout poc. zobrazeni tak, aby se}
                           {tento znak kompletne vypsal}

        konec_psani:=true; {jsme na pravem okraji - nema smysl dale psat}
        end;

      3:{castecne moc vpravo}
        begin
        ss^.lch:=znak;
        _posunv:=w1+w4-fnf_target^.breite+1;
        konec_psani:=true; {jsme na pravem okraji - nema smysl dale psat}
        end;

      2:{uplne moc vlevo}
        begin
        _posunm:=w4;
        {DEBUG --- if ss^.delka>20 then outtext(vga,a*10,570,char(znak),64000);}
        end;

      4:{castecne moc vlevo}
        begin
        _posunm:=-w1;
        {DEBUG --- if ss^.delka>20 then outtext(vga,a*10,570,char(znak),65535);}
        end;

      end;


   if FNP=true then
      for b:=0 to 2 do
          if (FN_poloha[b].B=URCIZNAK) then {hlidej pozici kurzoru}
             if (a=FN_poloha[b].N) then
                begin
                FN_poloha[b].x:=w1;{+w4-f^.znak^[znak].relX;}
                {if FN_poloha[b].x>target^.breiteminus1 then
                   FN_poloha[b].x:=target^.breiteminus1;}
                FN_poloha[b].y:=w2;
                FN_poloha[b].B:=NORMAL;  {Nalezeno. Uz s tim nebudeme hybat!}
                end;
   x:=x+w4;
   end;

inc(a);
until (a>ss^.up) or (konec_psani=true);

if FNP=true then
   for b:=0 to 2 do
       if (FN_poloha[b].B=URCIZNAK) then {hlidej pozici kurzoru}
          if FN_poloha[b].N=a then
             begin
             FN_poloha[b].x:=x;
             FN_poloha[b].y:=w2;
             FN_poloha[b].B:=normal;
             end
             else
          if FN_poloha[b].N>a then
             begin
             FN_poloha[b].x:=x+w4;
             FN_poloha[b].y:=w2;
             FN_poloha[b].B:=normal;
             end;


{}Preskok:{}

ss^.odz:=_odz;
ss^.doz:=_doz;
ss^.posunv:=_posunv;
ss^.posunm:=_posunm;

while q<>nil do    {jeste zpracuju uzly lezici mimo zobrazovanou oblast}
   begin
   vv:=q^.vazba;
   NastavAtributy(vv,false,x,y,f);
   q:=q^.dalsi;
   end;

{if FN_DEBUG and FN_odlisovat_char_0 then}

if FN_vyznacovat_konec_radky then
   begin
   if ss^.crlf=0 then a:=FN_COLOR_K0 else
   if ss^.crlf=1 then a:=FN_COLOR_K1 else a:=FN_COLOR_K2;
   circle(fnf_target^,x,y,4,a);
   end;

Obnov_Atributy_PIt_z_bufferu(@buffer_na_atributove_promenne);
end;


Function Zjisti_X(poz:longint;ss:PItRadek):longint;
var a,xx:longint;
    q:PUzel;
    vv:PFNatrb;
    c:word;
    f:PFont;
    zalozprvni:boolean;
    oneprop:boolean;

begin
if poz<=1 then Exit(0);
if poz>ss^.up then Exit(ss^.gd+1);


oneprop:=FN_neproporcionalni;

if ss^.aa=nil then begin q:=nil;vv:=nil;f:=fn_default_fn;end
              else begin
                   q:=ss^.aa^.first;vv:=q^.vazba;f:=vv^.font;
                   FN_neproporcionalni:=(vv^.modifikace and (64+32))<>0;
                   end;


xx:=0;
for a:=1 to poz-1 do
   begin
   if q<>nil then
       if a=vv^.pozice then  {meni se na teto pozici atribut textu?}
          begin
          f:=vv^.font;
          FN_neproporcionalni:=(vv^.modifikace and (64+32))<>0;
          q:=q^.dalsi;                 {a o ted se zajimej o pristi zmenu}
          if q<>nil then vv:=q^.vazba else vv:=nil;
          end;
   c:=ss^.Znak(a);
   inc(xx,SirkaZnaku(f,c));
   end;
FN_neproporcionalni:=oneprop;
Zjisti_X:=xx;
end;


Function Tagy_na_Vaznik(s:pchar;delka_s:longint;f:PFont):PItRadek;
var i,j,k,l,n,so,su:longint;
      {q:PVaznik;}
      ff:PFont;
      e:PItRadek;
      v,v2{,vp}:pfnatrb;
      p:PVaznik;
      dl,dl2:byte;
      t:string;
      buffer_na_atributove_promenne:array[0..255] of byte;
      zalozprvni:boolean;
      zal_utf8_konv:longint;

begin
{Procedura je slozitejsi, nez by clovek cekal, kvuli tomu, ze se snazi plnit
PItRadek po delsich usecich, a ne proste po pismenkach. Takhle je to mnohem
rychlejsi}

Schovej_Atributy_PIt_do_bufferu(@buffer_na_atributove_promenne);
{schovame aktualni nastaveni parametru fontu, barev, atd}


if fnf_zasobniky=@fnf_zasobniky_def then
   begin
   fnf_zasobniky^.Vynuluj;
   fnf_zasobniky^.Uloz_FN_promenne_do_i0;
   end;

e:=New(PItRadek,Init);  {nema zakladni uzel}

{writeln(e^.up);readln;}

i:=0;
k:=1;
l:=0;
n:=1;

zal_utf8_konv:=UTF8_konv;
v2:=Tag_to_FNatrb('',so,su);

if f<>nil then
   begin
   {v2:=Tag_to_FNatrb('',so,su);
   ff:=fn_default_fn;}
   fn_default_fn:=f;
   end;

if fn_default_fn^.unicode=true
   then UTF8_konv:=UTF8_ALL_CONV
   else UTF8_konv:=UTF8_NO_CONV;

{if debuglevel>50 then
   begin
   writeln('tagy_na_vaznik');
   readln;
   debuglevel:=debuglevel;
   end;}

{if debuglevel<=50 then} {e^.PrvniUzel;}

while s[i]<>#0 do
   begin
   if (s[i]='<') and (s[i+1]<>'<') then
      begin
      {Zacina tu tag?}
      if l<>0 then e^.VlozKus(s,e^.up+1,n,l);
      l:=0;
      t:=Vysekni_Tag(s,i+1,delka_s,j);
      if t[length(t)]<>'>' then Break;  {neuzavreny tag?}

      {if Pos('KLAVESY=NN#1;BARVA=!',t)<>0 then}  {debug}
         {debuglevel:=51;}

      v:=Tag_to_FNatrb(t,so,su);

      if debuglevel>0 then
         begin
         writeln(t);
         writeln(so,' : ',su);
         writeln(v^.barva);
         writeln(v^.extra^);
         readln;
         end;

      {e^.UmistiUzel(v,k);}
      e^.UmistiUzelBezKontrolyStavajiciho(v,k,true {na konec});
      {Pozor, <e^.UmistiUzelBezKontrolyStavajiciho> nedela kopii V.
       Proto zde V nemuzeme rusit}

      if pfont(v^.font)^.unicode=true
         then UTF8_konv:=UTF8_ALL_CONV
         else UTF8_konv:=UTF8_NO_CONV;

      if debuglevel>0 then
         begin
         writeln('porad OK');
         readln;
         end;

      {Kill_PfnAtrb(v);}    {Toto muzeme udelat, protoze UmistiUzel dela kopii}

      if debuglevel>0 then
         begin
         writeln(longint(v));
         readln;
         end;

      inc(i,j);
      n:=i+2;
      end
      else begin
      {Zde tag neni?}

      {ale co kdyz tu jsou zvlastnosti s vetsi-mensi?}
      if (s[i]='<') or (s[i]='>') then
         begin
         e^.VlozKus(s,e^.up+1,n,l+1);
         l:=0;
         if (s[i]='<') or (s[i+1]='>') then inc(i);
         n:=i+2;
         end
      else inc(l);
      inc(k);
      end;
   inc(i);
   end;
   if l<>0 then e^.VlozKus(s,e^.up+1,n,l);

zalozprvni:=false;

if e^.aa=nil then zalozprvni:=true
   else begin
   v:=e^.aa^.first^.vazba;
   if v^.pozice>1 then zalozprvni:=true;
   end;

if zalozprvni=true
   then e^.UmistiUzelBezKontrolyStavajiciho(v2,1,false {na zacatek})
   else Kill_PfnAtrb(v2);

{Behem zpracovavani jsme nenarazili za zadny tag? V tom pripade se nevytvoril
 ani zadny uzel, ale to je problem, protoze uzel potrebujeme}

if f<>nil then   {na pocatku jsme si vynutili jiny font nez aktualni?}
   begin         {v tom pripade se na konci retezce k aktualnimu explicitne vratime}
   {if debuglevel>50 then begin writeln('v bloku "if f<>nil"');readln;end;}
   {e^.UmistiUzel(v2,e^.up+1);}
{debug}   {e^.UmistiUzelBezKontrolyStavajiciho(v2,e^.up+1);}
   {Kill_PfnAtrb(v2);}    {Toto muzeme udelat, protoze UmistiUzel dela kopii}
   fn_default_fn:=ff;
   end;

Schovej_Atributy_PIt_do_bufferu(@FNfont3_buffer_na_atributove_promenne);

Obnov_Atributy_PIt_z_bufferu(@buffer_na_atributove_promenne);
{obnovime parametry fontu, barev, atd (tak jak byly)}

UTF8_konv:=zal_utf8_konv;
Tagy_na_Vaznik:=e;
end;

Procedure Print_FN(x,y:longint;s:pchar;f:PFont);
{Velmi zjednodusena verze Print_IT. Nijak neresi tagy ani dalsi vymozenosti.
 Pro fonty v unicode ale ocekava kodovani UTF-8}
var i,mimo:longint;
    z,w1,w2,w4:longint;
    posun:byte;
begin
if s=nil then Exit;
i:=0;
if f^.unicode then
   begin
   while s[i]<>#0 do
      begin
      z:=byte(s[i]);
      z:=UTF82longint(s,maxlongint,i+1,posun);  {tato procedura cisluje od 1}
      mimo:=Print_Char(x,y,z,f,FN_color,w1,w2,w4);
      if mimo=1 then Break;
      inc(x,w4);
      inc(i,posun);
      end;
   end
   else begin
   while s[i]<>#0 do
      begin
      z:=byte(s[i]);
      mimo:=Print_Char(x,y,z,f,FN_color,w1,w2,w4);
      if mimo=1 then Break;
      inc(x,w4);
      inc(i);
      end;
   end;
end;

Procedure Print_FN(x,y:longint;s:string;f:PFont);
begin
s:=s+#0;
Print_FN(x,y,@s[1],f);
end;

Procedure Print_FN(x,y:longint;s:string);
begin
s:=s+#0;
Print_FN(x,y,@s[1],AktualniFont_FN);
end;

Procedure Print_FN(x,y:longint;s:pchar);
begin
Print_FN(x,y,s,AktualniFont_FN);
end;


Procedure Print_FNTag(x,y:longint;s:pchar;f:PFont);
var v:PItRadek;
    i:longint;
begin
i:=PLength(s);
v:=Tagy_na_vaznik(s,i,f);
Print_It(x,y,v);
Kill_PitRadek(v);
end;


Procedure Print_FNTag(x,y:longint;s:string;f:PFont);
begin
s:=s+#0;
Print_FNTag(x,y,@s[1],f);
end;


Function Vyska_FN(f:PFont):longint;
begin
if f=nil
   then Vyska_FN:=0
   else Vyska_FN:=f^.so+f^.su;
end;

Function Vyska_FN_aktual:byte;
var f:PFont;
begin
f:=AktualniFont_FN;
Vyska_FN_aktual:=Vyska_FN(f);
end;


Function Je_bitmapa_znaku(f:pfont;znak:longint):boolean;
var z:PZnak;
begin
if f=nil then Je_bitmapa_znaku:=false else
   begin
   if f^.IsChReadyZ(znak,z)
      then Je_bitmapa_znaku:=z^.HasBitmap
      else Je_bitmapa_znaku:=false;
   end;
end;


Function SirkaZnaku(e:PFont;znak:longint):longint;
{pokud neni definovan ZNAK, tak jako nahradu zkusi pouzit znak "O"}
var z,z79:PZnak;
    i:longint;
begin
{writeln('sirkaznaku: znak: ',znak);}
if e=nil
   then SirkaZnaku:=0
   else begin
   if e^.IsChReadyZ(znak,z)  {je definovan poptavany znak alespon na urovni rozmeru?}
      then begin
           if FN_neproporcionalni
              then i:=z^.bunek_np*e^.sbunky+e^.add
              else i:=z^.shift+e^.add;
           SirkaZnaku:=i;
           end
      else begin
      if e^.IsChReadyZ(79,z79)     {je definovan alespon znak "O"?}
         then begin
              if FN_neproporcionalni
              then i:=z^.bunek_np*e^.sbunky+e^.add
              else i:=z^.shift+e^.add;
              SirkaZnaku:=i;
              end
         else SirkaZnaku:=e^.sbunky+e^.add;
                                  {vse selhalo, tak vratme alespon}
                                  {sirku obrazove bunky pro neproporc. mod}
                                  {a ta sepouzije pro zobrazovani}
                                  {zastupneho znaku}
      end;
   end;
end;


Function SirkaBitmapyZnaku(e:PFont;znak:longint):longint;
{pokud neni definovan ZNAK, tak jako nahradu zkusi pouzit znak "O"}
var z,z79:PZnak;
begin
if Je_bitmapa_znaku(e,znak)      {je definovan poptavany znak?}
   then begin
   z:=e^.PrepChar(znak);
   SirkaBitmapyZnaku:=z^.sirka;
   end
   else begin
   if Je_bitmapa_znaku(e,79)       {je definovan alespon znak "O"?}
      then begin
           z79:=e^.PrepChar(79);
           SirkaBitmapyZnaku:=z79^.sirka;
           end
      else SirkaBitmapyZnaku:=FN_SIRKA_NEZNAMEHO_ZNAKU;
                                   {vse selhalo, tak vratme alespon}
                                   {nejakou definovanou hodnotu pro ucely}
                                   {zobrazovani zastupneho znaku}

   end;
end;


Function VyskaBitmapyZnaku(e:PFont;znak:longint):longint;
{pokud neni definovan ZNAK, tak jako nahradu zkusi pouzit znak "O"}
var z,z79:PZnak;
begin
if Je_bitmapa_znaku(e,znak)      {je definovan poptavany znak?}
   then begin
   z:=e^.PrepChar(znak);
   VyskaBitmapyZnaku:=z^.vyska;
   end
   else begin
   if Je_bitmapa_znaku(e,79)       {je definovan alespon znak "O"?}
      then begin
           z79:=e^.PrepChar(79);
           VyskaBitmapyZnaku:=z79^.vyska;
           end
      else VyskaBitmapyZnaku:=FN_VYSKA_NEZNAMEHO_ZNAKU;
                                   {vse selhalo, tak vratme alespon}
                                   {nejakou definovanou hodnotu pro ucely}
                                   {zobrazovani zastupneho znaku}
   end;
end;



Function SirkaEvDodatecneMezery(v:PItRadek):longint;
var f:Pfont;
    a:PfnAtrb;
begin
if v^.aa=nil then f:=FN_default_fn else
   begin
   a:=v^.aa^.last^.vazba;
   f:=a^.font;
   end;
SirkaEvDodatecneMezery:=SirkaZnaku(f,32);
end;


Function SirkaUseku_IT(s:pItradek;p:Puzel;poz,delka:longint):longint;
var f:PFont;
    a,b,c:longint;
    vv:pfnatrb;
    oneprop:boolean;

begin
b:=0;
oneprop:=FN_neproporcionalni;
if p<>nil then
   begin
   vv:=p^.vazba;
   f:=vv^.font;
   FN_neproporcionalni:=(vv^.modifikace and (64+32))<>0;
   end else f:=fn_default_fn;

for a:=poz to poz+delka-1 do
    begin
    if p<>nil then
       if a=vv^.pozice then    {meni se na teto pozici atribut textu?}
          begin
          f:=vv^.font;
          FN_neproporcionalni:=(vv^.modifikace and (64+32))<>0;
          p:=p^.dalsi;         {a o ted se zajimej o pristi zmenu}
          if p<>nil then vv:=p^.vazba else vv:=nil;
          end;
    c:=s^.Znak(a);
    inc(b,SirkaZnaku(f,c));
    end;
FN_neproporcionalni:=oneprop;
SirkaUseku_IT:=b;
end;

Function SirkaUseku_IT(s:pItradek;poz,delka:longint):longint;
var p:PUzel;
begin
p:=s^.VratUkazatelNaUzel(poz);
SirkaUseku_IT:=SirkaUseku_IT(s,p,poz,delka);
end;

Function Sirka_IT(s:PItRadek):longint;
begin
Sirka_IT:=SirkaUseku_IT(s,1,s^.up);
end;

Function Sirka_FN(s:pchar;e:PFont):longint;
var v:PItRadek;
    i:longint;
begin
{UlozZasobniky;}
i:=PLength(s);
v:=Tagy_na_vaznik(s,i,e);
{ObnovZasobniky;}
Sirka_FN:=v^.gd;
Dispose(v,Done);
end;

Function Sirka_FN(s:string;e:PFont):longint;
begin
s:=s+#0;
Sirka_FN:=Sirka_FN(@s[1],e);
end;

Function Sirka_FN_na_Xpoz(p:pchar;font:PFont;x:longint):longint;
{Da sirku toho, co je pred kurzorem}
var c:char;
    xx:longint;
begin
dec(x);
c:=p[x];
p[x]:=#0;
xx:=Sirka_FN(p,font);
p[x]:=c;
Sirka_FN_na_Xpoz:=xx;
end;

Function Pozice_v_Retezci_IT(x,xs,spx:longint;ss:PItRadek;mod_mysi:boolean):longint;
{X relativni souradnice mysi bez pricteni Poc_Zobr}
{XS ze zacatku byva Poc_ZobrX}
{SPX je odsazeni prvniho znaku v radce pokud neni odrolovano}
var obx,bx:longint;
    f:PFont;
    a,c:longint;
    vv:pfnatrb;
    q:PUzel;

begin
if ss^.aa=nil then begin q:=nil;vv:=nil;f:=fn_default_fn;end
              else begin q:=ss^.aa^.first;vv:=q^.vazba;f:=vv^.font;end;
FN_skut_znak:=0;
FN_poz_v_ret_delka_radky:=0;
if ss^.up=0 then Exit(1);    {nejsem si uplne jisty, ma-li tu byt 1 nebo 0}

if x=xs then Exit(1);

if x<xs-spx then Exit(0);
if x<=xs then Exit(1);

bx:=xs+spx;
for a:=1 to ss^.delka do
    begin
    if q<>nil then
       if a=vv^.pozice then  {meni se na teto pozici atribut textu?}
          begin
          f:=vv^.font;
          q:=q^.dalsi;                 {a o ted se zajimej o pristi zmenu}
          if q<>nil then vv:=q^.vazba else vv:=nil;
          end;
    c:=ss^.Znak(a);
    obx:=bx;
    inc(bx,SirkaZnaku(f,c));
    if (bx>x) then
       begin
       FN_poz_v_ret_delka_radky:=bx-xs+1;
       if mod_mysi
          then if bx-x>x-obx then Exit(a) else Exit(a+1)
          else Exit(a);
       end;
    end;
Pozice_v_Retezci_IT:=a+1;
FN_poz_v_ret_delka_radky:=bx-xs+1;
end;

Function Pozice_v_Retezci(x,xs,spx:longint;s:pchar;f:PFont):longint;
var v:PItRadek;
    i,j:longint;
begin
{UlozZasobniky;}
j:=maxlongint div 2;   {trosku risk...}
v:=Tagy_na_Vaznik(s,j,f);
{ObnovZasobniky;}
i:=Pozice_v_Retezci_IT(x,xs,spx,v,true);
Pozice_v_Retezci:=i;
end;

Procedure Init_FNSLR;
begin
{FN_selector:=NovyVaznik;}
end;

Procedure Kill_fnslr(var p:pointer);
begin
{dummy}
end;

Procedure Znic_FNSLR;
begin
{Vaznik_Done_all(FN_selector,@Kill_fnslr);}
end;


Function Najdi_ve_FNSLR_VGA(velikost:byte):pfont;
var a,b:longint;
    hh:PObecnyFont;
    f:pfont;

begin
b:=1;
repeat
   a:=Venom_mng_GetFontSlot_by_name('VGARAM._HW_',b);
   if a=0 then Exit(nil);
   hh:=Venom_mng_GetFontPtr(a);
   f:=hh^.fdata;
   if f^.vel=velikost then Exit(f);
   inc(b);
until b>255;
end;


Function Najdi_ve_FNSLR(s:string):pfont;
var h:PObecnyFont;
    a,b:longint;
    f:PFont;

begin
b:=0;
for a:=1 to MAX_PREDEF_FN_NAMES do {napred orestuju preddefinovane nazvy (aliasy)}
    if predef_fn[a]=nil then Break else
       if predef_fn[a]^=s then begin b:=a;Break;end;

if b<>0 then  {chceme tedy nejaky preddefinovany alias?}
   begin
   if b=1 then Exit(Najdi_ve_FNSLR_VGA(16));
   if b=2 then Exit(Najdi_ve_FNSLR_VGA(14));
   if b=3 then Exit(Najdi_ve_FNSLR_VGA(8));
   f:=predef_fn_fn[b];
   Najdi_ve_FNSLR:=f;
   Exit;
   end;

a:=Venom_mng_GetFontSlot_by_name(s,1);
if a=0 then Exit(nil);
h:=Venom_mng_GetFontPtr(a);
Najdi_ve_FNSLR:=h^.fdata;
end;


Function Nacti_FNSLRV(s:string;vel:longint):PFont;
var v:pfnslr;
    f:PFont;
    h:PObecnyFont;
    t:string;
    a,b,vvel:longint;
    l,sb:longint;

begin
FN_error:=FN_OK;
{s:=Convert_up(s);}
vvel:=vel;

b:=0;
for a:=1 to MAX_PREDEF_FN_NAMES do {napred orestuju preddefinovane nazvy (aliasy)}
    if predef_fn[a]=nil then Break else
       if predef_fn[a]^=s then begin b:=a;Break;end;

if b<>0 then  {chceme tedy nejaky preddefinovany alias?}
   begin
   if b=1 then {FN_FONT_VGA16}           {aliasy pro VGA fonty}
      begin s:='VGA';vvel:=16;end else
   if b=2 then {FN_FONT_VGA14}
      begin s:='VGA';vvel:=14;end else
   if b=3 then {FN_FONT_VGA8}
      begin s:='VGA';vvel:=8;end
      else begin            {nejaky jiny alias pro PFont nekde v pameti?}
      f:=predef_fn_fn[b];   {v tom pripade...}
      Nacti_FNSLRV:=f;       {...jen nastav ukazatel...}
      Exit;                 {...loader nevolej a skonci}
      end;
   end;

l:=Venom_mng_SetFontStyle(s,vvel,0);  {bud vyhleda nacteny font nebo nacte nove}
if l<0 then FN_error:=FN_LOADERROR;

h:=Venom_mng_GetActFontPtr;
f:=h^.fdata;
Nacti_FNSLRV:=f;
end;


Function Nacti_FNSLR(s:string):PFont;
begin
Nacti_FNSLR:=Nacti_FNSLRV(s,FN_default_loader_vel);
end;


Function FNSLR_dej_ID(f:PFont):string;
var s:string;
begin
if f=nil then Exit('');

s:=f^.rez;
if s='VGARAM._HW_' then
   begin
   if f^.vel=8 then Exit(FN_FONT_VGA8);
   if f^.vel=14 then Exit(FN_FONT_VGA14) else Exit(FN_FONT_VGA16);
   end;


if s='VGAROM._HW_' then  {TODO - predelat na konstanty pro VGA ROM}
   begin
   if f^.vel=8 then Exit(FN_FONT_VGA8);
   if f^.vel=14 then Exit(FN_FONT_VGA14) else Exit(FN_FONT_VGA16);
   end;

FNSLR_dej_ID:=s;
end;


Function OdstranTagy(s:ansistring):ansistring;
var i,j,k,l:longint;
    t:ansistring;
begin
i:=1;
t:='';
j:=Length(s);
repeat
if (s[i]='<') then
   if (s[i+1]='<') then begin inc(i);t:=t+'<<';end
     else begin
     {nasli jsme tag}
     k:=i;
     while s[i]<>'>' do inc(i);
        {if i<=j then inc(i) else begin dec(i);Break;end;}
     end
     else t:=t+s[i];
inc(i);
until i>j;
OdstranTagy:=t;
end;

Function SmazMezery_v_tagach(t:ansistring):ansistring;
var a,b,j:longint;
    v_tagu:boolean;
begin
a:=1;
j:=Length(t);
v_tagu:=false;
repeat
b:=1;
if t[a]='>' then v_tagu:=false else
if t[a]='<' then v_tagu:=not v_tagu else
   if v_tagu and (t[a]=' ') then
      begin delete(t,a,1);dec(j);b:=0;end;
inc(a,b);
until a>j;
SmazMezery_v_tagach:=t;
end;

Function PocetTagu(s:ansistring):longint;
var i,j,k,l:longint;
begin
i:=1;
l:=0;
j:=Length(s);
repeat
if (s[i]='<') then
   if (s[i+1]='<') then inc(i)
     else begin
     {nasli jsme tag}
     k:=i;
     while s[i]<>'>' do inc(i);
        {if i<=j then inc(i) else begin dec(i);Break;end;}
     inc(l);
     end;
inc(i);
until i>j;
PocetTagu:=l;
end;

Function Dej_nty_tag(s:ansistring;n:longint):string;
var i,j,k,o:longint;
    t:string;
begin
i:=1;
o:=0;
t:='';
j:=Length(s);
repeat
if (s[i]='<') then
   if (s[i+1]='<') then inc(i)
     else begin
     {nasli jsme tag}
     k:=i;
     inc(o);
     while s[i]<>'>' do inc(i);
        {if i<=j then inc(i) else begin dec(i);Break;end;}
     if o=n then
        begin
        t:=Copy(s,k,i-k+1);
        break;
        end;
     end;
inc(i);
until i>j;
Dej_nty_tag:=t;
end;

Function Jsou_def_znaky_pro_str(s:string;f:PFont):longint;
var i,j:longint;
    ap:byte;
    w:word;
    zz:PZnak;

begin
s:=OdstranTagy(s);
j:=Length(s);
i:=1;
if f^.unicode then
   repeat
   w:=UTF82longint(@s[1],j,i,ap);
   if Je_bitmapa_znaku(f,w)=false then Exit(i);
   inc(i,ap);
   until i>j
   else
   for i:=1 to Length(s) do
       begin
       zz:=f^.PrepChar(byte(s[i]));
       if (zz=nil) or (zz^.isready=false) then Exit(i);
       end;
Jsou_def_znaky_pro_str:=0;
end;

Function NajdiTag(s:ansistring;tag:string;var separat:string):longint;
var a,b,c,d:longint;
    v_tagu:boolean;
    t:ansistring;
begin
b:=Length(s);
v_tagu:=false;
tag:=Convert_Up(tag);
c:=Length(tag);
t:=Convert_Up(s);
for a:=1 to b do
    begin
    if t[a]='>' then v_tagu:=false else
    if t[a]='<' then v_tagu:=not v_tagu else
    if v_tagu and (Copy(t,a,c)=tag) then
       begin
       d:=a;
       repeat inc(d);
       until (d>=b) or (t[d+1]=';') or (t[d+1]='>');
       separat:=Mid(s,a,d);
       Exit(a);
       end;
    end;
separat:='';
NajdiTag:=0;
end;


Procedure FontAdr(s:string);
begin
if (ExistDir(s)=false) and (s<>'') Then Exit;
ADRESAR_S_FONTY:=s;
end;

Function GetFontAdr:string;
begin
GetFontAdr:=ADRESAR_S_FONTY;
end;

Procedure DefaultniZpracovaniChyby;
begin
end;


Procedure Init_FNfont3;
var b:byte;
begin
{MyVGA_2_FN;}
Init_FNSLR;

predef_fn[1]:=@FN_FONT_VGA16;
predef_fn[2]:=@FN_FONT_VGA14;
predef_fn[3]:=@FN_FONT_VGA8;

for b:=4 to MAX_PREDEF_FN_NAMES do
    begin
    predef_fn[b]:=nil;
    predef_fn_fn[b]:=nil;
    end;


FN_VGA16:=Nacti_FNSLR(FN_FONT_VGA16);
{Nacti_FNSLR(FN_FONT_VGA16_U);}
FN_VGA14:=Nacti_FNSLR(FN_FONT_VGA14);
FN_VGA8:=Nacti_FNSLR(FN_FONT_VGA8);


fnf_zasobniky_def.Vynuluj;
fnf_zasobniky:=@fnf_zasobniky_def;

NastavAktualniFont(FN_FONT_VGA16);
for b:=0 to 2 do FN_poloha[b].B:=NORMAL;



NastavVystupTextu(@vga);
FNfont3_error_proc:=@FNfont3_error_default;
end;

begin

{Init_FNfont3;}
Venom_mng_Init_graph_list(@Init_FNfont3);
{Opozdena inicializace jednotky. Nebude se volat ted, ale az pri
 VenomGFX.Init_Graph}
end.
