Technický článek

Delphi HotPDF Hello World: Váš první program pro PDF

Každá knihovna PDF obsahuje příklad „hello world“ a u toho od HotPDF stojí za to se zastavit, protože ten nejmenší program, který něco dělá, vás už nutí ke dvěma rozhodnutím, která budete následně opakovat u každého dokumentu: jaké písmo nastavit a kam na stránce text umístit. Pokud tyto dvě věci zvládnete správně, zbytek API jsou jen variace na toto téma. Zde je to celé, konzolový program, který napíše jedinou stránku a pozdraví čtenáře v téměř tuctu jazyků:

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.

Vícejazyčné Hello World PDF vytvořené komponentou HotPDF v Delphi

To je celý příklad. Volání THotPDF.Create(nil) spárované s try/finally ... Free je běžný vzor vlastnictví v Delphi a PDF na tom nic nemění. Co si zaslouží pozornost, je vnitřní páteř o čtyřech krocích: nastavení vlastností, BeginDoc, kreslení, EndDoc. Toto pořadí nelze zaměnit

Před BeginDoc nastavte vlastnosti dokumentu

BeginDoc je okamžik, kdy HotPDF potvrdí (commitne) strukturu dokumentu, takže vše, co ovlivňuje celý soubor, musí být nastaveno před ním. Compression := cmFlateDecode zapíná kódování FlateDecode pro datové toky (content streams), což tvoří rozdíl mezi kompaktním a zbytečně nabobtnalým souborem. FontEmbedding := True přibalí písmo, kterým kreslíte, do souboru, takže dokument bude vypadat stejně na stroji, kde nikdy nebylo nainstalováno písmo Arial Unicode MS, jako u vás. Pokud kteroukoli z těchto vlastností přiřadíte až po BeginDoc, tiše to na již rozpracovaném dokumentu neudělá nic a neupozorní vás žádná chyba

SetFont, pak TextOut, a dávejte pozor na počátek (origin)

Na prvních vykreslovacích voláních každého zaskočí dvě věci. Tou první je pořadí: SetFont se musí provést před každým TextOut, které na něm závisí, a musí se zopakovat po každém AddPage, protože aktuální písmo nepřežije zalomení stránky. Druhou je souřadnicový systém. TextOut měří od levého dolního rohu stránky, nikoliv od levého horního, přičemž Y se směrem nahoru zvětšuje, a to v bodech (1/72 palce). Proto zde řádky kráčejí směrem dolů z hodnoty 760, každý o 30 bodů níže než ten předchozí. Každý, kdo přichází ze světa počítačové grafiky, předpokládá opak a napíše první řádek rovnou mimo spodní okraj stránky

Jedno písmo, mnoho abeced (skriptů)

Důvodem, proč jedno volání SetFont zvládne latinku, cyrilici, japonštinu a čínštinu na jedné stránce, je samotný typ písma: Arial Unicode MS do jednoho souboru balí glyfy pro téměř každé písmo. Čtvrtým argumentem funkce SetFont je znaková sada Windows a předání DEFAULT_CHARSET umožňuje systému vybírat glyfy pro každý řetězec zvlášť, místo aby vše vázal na jednu zastaralou kódovou stránku. S tímto pohodlím se však pojí dvě upozornění. Písmo musí být přítomno na stroji, který PDF sestavuje, protože HotPDF vloží to, na co OS název přeloží; pokud Arial Unicode MS chybí, Windows jej tiše zamění za náhradu a váš text CJK (čínština-japonština-korejština) se může zobrazit jako prázdné rámečky. Navíc nepokrývá všechna písma rovnocenně: pro písma psaná zprava doleva, jako je arabština a hebrejština, nebo pro cokoliv, co vyžaduje složité tvarování (shaping), sáhněte po specializovaném písmu nahraném pomocí RegisterUnicodeTTF a volání textu zprava doleva, což je téma samo pro sebe

Spusťte to a v pracovním adresáři získáte HelloWorld.pdf: jednu stránku, několik řádků vícejazyčného textu, zkomprimováno a s vloženým písmem. Jasnými dalšími kroky jsou přidělení velikosti, stylu a rotace tomuto textu, stejně jako cílené umístění více než jednoho bloku textu. Obojí probírá ukázka TextOut sample. Když chcete kreslit čáry, rámečky a obrázky, nejen text, stejný objekt stránky obsahuje i tato volání

Zde zobrazená volání TextOut, SetFont a volání dokumentu jsou součástí HotPDF Component pro Delphi a C++Builder