Posuvný text v DelphiX podruhé - Builder.cz - Informacni server o programovani

Odběr fotomagazínu

Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!

 

Zadejte Vaši e-mailovou adresu:

Kamarád fotí rád?

Přihlas ho k odběru fotomagazínu!

 

Zadejte e-mailovou adresu kamaráda:

Soutěž

Sponzorem soutěže je:

IDIF

 

Kde se koná výstava fotografií Luďka Vojtěchovského?

V dnešní soutěži hrajeme o:



Delphi

Posuvný text v DelphiX podruhé

delphix_bitmalfont

14. září 2001, 00.00 | V dnešním pokračování minulého článku najdete podrobný popis tvorby bitmapového textu s nevyhlazeným okrajem ve Photoshopu a popis programu pro zobrazení textu v delphiX, kdy bude každé písmeno jinak široké !



Jenom na úvod - když jsem v minulém článku psal o tom, že tvorba grafiky pro program je piplavá práce, nemyslel jsem to vážně. Co to je piplavá práce poznáte až v článku dnešním :))

Tedy, jako v minulém článku se i dnes pokusíme nakreslit nějaké hezké písmo které potom využijeme v programu. Narozdíl od minulého však bude písmo s okrajem bez vyhlazení, aby bylo použitelné na jakoukoliv barvu pozadí, a každé písmeno bude mít jinou šířku, aby k ostatním hezky pasovalo. Ještě jsem vás neodradil ? Tak se do toho dáme!

Z minule tady mám ještě jedno písmo, jedná se o nevyhlazený font Tahoma, velikost 8 bodů s černým okrajem. Jednotlivá písmena jsou 15x15 pixelů velká, pro lepší výsledek je dobré kreslit je šířkou 10 pixelů. Jak jdou písmena po sobě je napsáno hned za obrázkem:


ABCDEFGHIJKLMNOPQRSTUVXYZ 0123456789-:?/*-+


Grafika
(9/10 dnešní práce)

Ale zpět k práci dnešní - nejprve potřebujeme nějaký ten grid. Použijeme velikost políčka 45x45 pixelů, velikost gridu bude 10x10 polí. Celková velikost obrázku tedy bude 450x450 pixelů. V každém políčku si navrhneme polohu řádku (u malých písmen bude výš, jelikož mnoho malých písmen zasahuje pod řádek, ve výsledném programu to samozřejmě srovnáme) a střed, podle barev si ještě rozdělíme co kam patří. Zde je náhled na grid, který jsem nakreslil já a za ním legenda k barvě políček (na nakreslení gridu si bohatě vystačíte s malováním). Obrázky jsou to dva, tudíž si můžete obrázek s mřížkou rovnou uložit na disk:




Pro dnešek jsou použil písmo Chiller LET, stáhnout si jej můžete dole v downloadu. Jak budou jednotlivá písmena následovat po sobě vidíte zde:


ABCDEFGHIJ KLMNOPQRST UVWXYZ abc defghijklm nopqrstuvw xyz0123456 789/*-?.:% !;{<>@#&$% |§µ±†~}ßŘĆ


Spustíme si tedy Photoshop a dáme se do práce. Nejprve vytvoříme nový obrázek velikosti 450x450 pixelů a vložíme vrstvu s mřížkou. Dále zvolíme text a vložíme všechny znaky. Ty podle návodu z minulého článku alespoň přibližně rozházíme do políček. Pokud máte výkonější počítač, můžete si rovnou nastavit efekty vrstvy, pokud ne, počkejte, a nastavte si je až po dokončení. Pokud máme všechna písmena tam kde mají být, textovou vrstvu vykreslíme (Layer / Rasterize / Type nebo klikneme pravým tlačítkem na vrstvu a zvolíme Rasterize Layer). Tím máme z písma obrázek a postoupíme k další věci. To jest vytvoření 1 pixel širokého nevyhlazeného rámečku. Provedeme to celkem jednoduše - načteme si výběr textové vrstvy - Select / Load Selection:


Dále zvolíme Select / Grow (to je hodně důležité) a ještě výběr rozšíříme právě o jeden pixel - Select / Modify / Expand - 1pixel - OK:


Pod naší vrstvou vytvoříme vrstvu novou, přepneme na ní, a vyplníme ji černou barvou - Edit / Fill - Black - OK.


Tím máme hotov i černý obtah kolem vrstvy s textem:


A postoupíme k věci další. Tím bude ta "nejpiplavější" práce, která nás dnes čeká. Pokusíme se každé písmeno zvlášť vycentrovat, položit na řádek a ještě zjistit jeho šířku. To celé pro všech 90 znaků. Vytvoříme tedy pár vrstev, které budou vysoké jedno políčko (45 pixelů), a budou mít šířku od 10 do 30 pixelů. Vždy po čtyřech pixelech, tudíž bude vrstev 6. Vyplňte je černou barvou a u každé nastavte průhlednost např. na 20%. Vyberte všech šest vrstev a slučte je dohromady. Dále vrstvu s tímto obrazcem přesuňte nad první znak, velké písmeno A (přesně na střed). Podle vrsty nad písmenem, kterou jsme si právě vytvořili hned poznáte, je-li písmeno ve středu. Pokud tomu tak není, musíte ho přesunout. Naučte se používat klávesové zkratky, jinak vás za chvíli budou bolet prsty od klikání na myši. Poté podle naší pomocné vrstvy odhadněte šířku písmene, zapiště si ji a posuňte vrstvu nad další písmeno. Takto to udělejte devadesátkrát a je to. Pro ty, kterým se do toho nějak nechce je tady seznam všech šířek a náhled na vycentrovaná písmena:

A B C D E F G H I J 26, 24, 24, 22, 22, 18, 18, 18, 20, 26 K L M N O P Q R S T 22, 20, 26, 24, 22, 20, 28, 24, 16, 28 U V W X Y Z _ a b c 20, 22, 28, 26, 24, 26, 20, 16, 16, 16, d e f g h i j k l m 16, 16, 16, 16, 16, 10, 18, 16, 10, 22, n o p q r s t u v w 16, 16, 16, 18, 12, 16, 16, 16, 16, 18, x y z 0 1 2 3 4 5 6 16, 18, 22, 22, 16, 22, 22, 22, 22, 18, 7 8 9 / * - ? . : % 22, 24, 22, 24, 18, 18, 18, 10, 10, 24 ! ; { < > @ # & $ % 10, 10, 44, 24, 22, 34, 34, 24, 18, 24, | § µ ± † ~ } ß Ř Ć 42, 42, 22, 38, 42, 34, 42, 20, 28, 34


A slibovaný náhled:


Bylo to dřina. Teď už jen zneviditelníme vrstvu s gridem a celý obrázek uložíme:


A už konečně můžeme ten Photoshop vypnout. A dát se do programování.

Programování
(1/10 dnešní práce)

Spustíme tedy Delphi. Pro jednoduchost bude dost věcí shodných s programem minulým, a proto je nebudu popisovat. Hned na začátku si definujeme dvě konstanty. Zaprvé FindString, jehož funkci známe již z minula (připomenu - obsahuje všechny znaky jak jak jsou na obrázku po sobě) a pole z názvem pole, ve kterém budou uloženy šířky jednotlivých znaků. Vypadat to pak může nějak takto:


const
FindString : string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ a
bcdefghijklmnopqrstuvwxyz0123456789/*-?.:%!;{<>@#&$
%|§µ±†~}ßŘĆ';

pole:array [0..89] of integer =
(26, 24, 24, 22, 22, 18, 18, 18, 20, 26,
22, 20, 26, 24, 22, 20, 28, 24, 16, 28,
20, 22, 28, 26, 24, 26, 20, 16, 16, 16,
16, 16, 16, 16, 16, 10, 18, 16, 10, 22,
16, 16, 16, 18, 12, 16, 16, 16, 16, 18,
16, 18, 22, 22, 16, 22, 22, 22, 22, 18,
22, 24, 22, 24, 18, 18, 18, 10, 10, 24,
10, 10, 44, 24, 22, 34, 34, 24, 18, 24,
42, 42, 22, 38, 42, 34, 42, 20, 28, 34);


Dále si definujeme proměnnou DrawString jako v článku minulém a XPosun typu integer (minule proměnná XPos). Jelikož jsme v mřížce kreslili malé znaky abecedy trochu výš nad řádek, budeme je muset v projektu kreslit trochu níž. Proto je dobré vědět, je-li daný znak malé písmeno. Pro tento účel si tedy vytvoříme funkci, která nedělá nic jiného než že zjišťuje malé písmena:


function IsMalePismeno(ch:char):boolean;
var str_mpismena:string;
begin
 Str_mpismena:='abcdefghijklmnopqrstuvwxyz';
 Result:= Pos(ch,str_mpismena) <> 0;
end;


Dále si ještě vytvoříme proceduru Form1.OnCreate, ve které si všechny proměnné nastavíme:


procedure TForm1.FormCreate(Sender: TObject);
begin
 DrawString:='Test teXtu @ Jak to do sebe zapada !';
 XPosun:=DXDraw1.SurfaceWidth;
end;


A nyní se jži můžeme vrhnout na proceduru DXTimer.OnTimer. V ní si také definujeme pár proměnných, většinou pomocných, a to - i:integer (pomocná proměnná), PosX, PosY:integer (pozice aktuálního znaku), CharWidth:integer (šířka aktuálního znaku) a WholeWidth:integer (šířka celého textu před aktuálním znakem). Dále v proceduře zkontrolujeme, zda můžeme kreslit, a vyplníme plochu tmavě šedou barvou. Potom pro každé písmeno zvlášť zjistíme jeho šířku, pokud se jedná o malé písmeno tak ho ještě posuneme na úroveň ostatního textu. Zjistíme jeho x-ovou pozici (PosX) a pokud je ve viditelné oblasti, znak nakreslíme. Nakonec ještě celý text posuneme doleva, aby se posouval, a zkontrolujeme, nemá-li běžet odznovu. A to je celé. Zde je úplný výpis procedury DXTimer1.OnTimer:

procedure TForm1.DXTimer1Timer(Sender: TObject;
LagCount: Integer);
var i,
    PosX, PosY,        // pozice akt. písmene
    CharWidth,         // šířka aktuálního písmene
    WholeWidth:integer;// šířka všech písmen před aktuálním

begin
 if not DXDraw1.CanDraw then Exit;

 DXDraw1.Surface.Fill($004B4B4B);

 WholeWidth:=0;

 // celé kreslení...
 for i:= 1 to Length(DrawString) do
  begin

   PosY:=10; // y-ová pozice písmene

   if IsMalePismeno(DrawString[i]) then
    begin
     // málé pismena snížíme na úroveň ostatního
     // textu....
     Inc(PosY,5);
    end;

   // šířku znaku zjistíme z pole...
   CharWidth:=Pole[Pos(DrawString[i],FindString)-1];

   // znak nakreslíme na střed..
   // tj. PosX nastavíme na polovinu šířky
   PosX:=(WholeWidth+(CharWidth div 2))+XPosun;
   // ale celá šířka počítá se znakem celým..
   WholeWidth:=WholeWidth+CharWidth;

   // pokud je písmeno viditelné, tak nakreslit
   if (PosX > -45) and (PosX < DXDraw1.SurfaceWidth) then
   DXImageList1.Items.Find('font').Draw(DXDraw1.Surface,
   PosX,PosY,Pos(DrawString[i],FindString)-1);

  end;

 // celý text posunout doleva...
 Dec(XPosun,2);
 // když je zobrazen celý DrawString tak odznovu...
 if Xposun < -(WholeWidth+45) then
 XPosun:=DXDraw1.SurfaceWidth;

 // a flip...
 DXDraw1.FLip;
end;


Nyní již můžete program přeložit a spustit, a kochat se výsledkem:


Tím končí dnešní článek. A na co se můžete těšit příště ? Popis známé hry 15, nebo-li "patnáctky" v DelphiX...

Download

Stáhnout soubor s písmem Chiller LET (55 kB)
Stáhnout soubor Adobe Photoshop s obrázkem písma (187 kB)
Stáhnout zkomprimovaný projekt se zdrojáky v zip souboru (402 kB)


Obsah seriálu (více o seriálu):

Tématické zařazení:

 » Rubriky  » Delphi  

 » Rubriky  » Windows  

 

 

 

Nejčtenější články
Nejlépe hodnocené články

 

Přihlášení k mému účtu

Uživatelské jméno:

Heslo: