Tehnički članak

Delphi HotPDF Hello World: Vas prvi PDF program

Svaka PDF biblioteka isporucuje primer "hello world", a onaj iz HotPDF-a vredi detaljnije razmotriti, jer i najmanji program koji radi bilo sta vec zahteva dve odluke koje cete ponavljati u svakom dokumentu nakon toga: koji font postaviti i gde na stranici tekst treba da se pojavi. Kada ove dve stvari ispravno podesite, ostatak API-ja su varijacije na temu. Evo celog primera, konzolnog programa koji pise jednu stranicu i pozdravlja citaoca na skoro tucetu jezika:

program HelloWorld;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,   // for DEFAULT_CHARSET; on pre-XE2 Delphi use plain Windows
  HPDFDoc;          // HotPDF main unit

procedure CreateHelloWorld(const FileName: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := FileName;
    Pdf.Compression := cmFlateDecode;   // shrink the content streams
    Pdf.FontEmbedding := True;          // embed the face so it renders anywhere
    Pdf.BeginDoc;

    // One face covering many scripts. The 4th argument is the Windows charset;
    // DEFAULT_CHARSET lets the system pick glyphs per string.
    Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 14, DEFAULT_CHARSET);

    // TextOut measures from the BOTTOM-LEFT corner, in points, Y growing upward.
    Pdf.CurrentPage.TextOut(72, 760, 0, 'Hello, Delphi PDF world!');     // English
    Pdf.CurrentPage.TextOut(72, 730, 0, 'Hola, mundo Delphi PDF!');      // Spanish
    Pdf.CurrentPage.TextOut(72, 700, 0, 'Hallo, Delphi PDF Welt!');      // German
    Pdf.CurrentPage.TextOut(72, 670, 0, 'Bonjour, monde PDF Delphi!');   // French
    Pdf.CurrentPage.TextOut(72, 640, 0, 'Ciao, mondo Delphi PDF!');      // Italian
    Pdf.CurrentPage.TextOut(72, 610, 0, 'Olá, mundo Delphi PDF!');       // Portuguese
    Pdf.CurrentPage.TextOut(72, 580, 0, 'Здравствуйте, Delphi PDF мир!'); // Russian
    Pdf.CurrentPage.TextOut(72, 550, 0, 'こんにちは、Delphi PDFの世界!');    // Japanese
    Pdf.CurrentPage.TextOut(72, 520, 0, 'Merhaba, Delphi PDF dünyası!');  // Turkish
    Pdf.CurrentPage.TextOut(72, 490, 0, '你好,Delphi PDF世界');           // Chinese
    Pdf.CurrentPage.TextOut(72, 460, 0, '여보세요, Delphi PDF 세계!');      // Korean

    Pdf.EndDoc;
  finally
    Pdf.Free;
  end;
end;

begin
  CreateHelloWorld('HelloWorld.pdf');
  Writeln('Wrote HelloWorld.pdf');
end.

Multilingual Hello World PDF produced by the HotPDF component in Delphi

To je citav primer. Kombinacija THotPDF.Create(nil) i try/finally ... Free predstavlja uobicajeni Delphi obrazac vlasnistva, i PDF to ne menja. Ono sto zasluzuje paznju je cetvorokoracna osnova u unutrasnjosti: postavljanje svojstava, BeginDoc, crtanje, EndDoc. Redosled nije zamenljiv

Podesavanje svojstava dokumenta pre BeginDoc

BeginDoc je trenutak kada HotPDF definise strukturu dokumenta, tako da sve sto utice na ceo fajl mora biti podeseno pre toga. Postavljanje Compression := cmFlateDecode ukljucuje FlateDecode za tokove sadrzaja, sto cini razliku izmedju kompaktnog fajla i nepotrebno naduvenog. Postavljanje FontEmbedding := True pakuje font kojim crtate direktno u fajl, tako da izgleda isto na masini koja nikada nije imala instaliran Arial Unicode MS kao i na vasoj. Dodelite bilo koje od ovih svojstava nakon BeginDoc i ono ce tiho nista ne uciniti dokumentu koji je vec u toku, bez ikakve greske koja bi vas upozorila

SetFont, zatim TextOut, i pazite na koordinatni pocetak

Dve stvari kod poziva za crtanje zbunjuju gotovo svakoga na prvoj stranici. Prva je redosled: SetFont mora biti pokrenut pre bilo kog poziva TextOut koji zavisi od njega, i mora biti ponoven nakon svakog poziva AddPage, jer trenutni font ne prezivljava prelom stranice. Druga stvar je koordinatni sistem. TextOut meri od donjeg levog ugla stranice, ne od gornjeg levog, sa Y koji raste kako se krece nagore, u tackama (1/72 inca). Zato linije ovde idu naniZe od 760, svaka po 30 tacaka ispod prethodne. Svako ko dolazi iz grafike za ekran pretpostavlja suprotno i pise prvu liniju direktno sa dna stranice

Jedan font, mnoga pisma

Razlog zasto jedan poziv SetFont moze nositi latinicu, cirilicu, japansko i kinesko pismo na istoj stranici je sam font: Arial Unicode MS pakuje glifove za gotovo svako pismo u jednu datoteku. Cetvrti argument za SetFont je Windows skup karaktera, a prosledivanje vrednosti DEFAULT_CHARSET sistemu dozvoljava da bira glifove po stringu umesto da sve vezuje za jednu zastarelu kodnu stranicu. Uz tu pogodnost idu i dva upozorenja. Font mora biti prisutan na masini koja gradi PDF, jer HotPDF ugradzuje ono u sta operativni sistem razresi naziv; ako Arial Unicode MS nedostaje, Windows ce tiho zameniti ga supstitutom i vas CJK tekst moze biti prikazan kao prazni kvadratici. Takode, ne pokriva svako pismo podjednako: za pisanje zdesna nalevo kao sto su arapski i hebrejski, ili bilo sta sto zahteva sloZeno oblikovanje teksta, koristite namenski font ucitan pomocu RegisterUnicodeTTF i pozive za tekst zdesna nalevo, sto je tema za sebe

Pokrenite program i dobicete fajl HelloWorld.pdf u radnom direktorijumu: jedna stranica, nekoliko redova visejezicnog teksta, kompresovano, sa ugradenim fontom. Ocigledni sledeci koraci su dodeljivanje velicine, stila i rotacije tom tekstu, kao i namerno postavljanje vise blokova teksta, sto sve primer TextOut prolazi korak po korak. Kada zelite da crtate linije, okvire i slike umesto samo teksta, isti objekat stranice drzi i te pozive

Pozivi TextOut, SetFont i pozivi za dokument prikazani ovde deo su HotPDF komponente za Delphi i C++Builder