Műszaki cikk

Delphi HotPDF Hello World: Az Ön első PDF programja

Minden PDF könyvtár szállít egy „hello world”-öt, és a HotPDF-nél érdemes lelassítani, mert a legkisebb program, amely csinál valamit, már két olyan döntésre kényszeríti Önt, amelyeket a későbbiekben minden dokumentumban meg fog ismételni: melyik betűtípust (font) állítsa be, és hol landoljon a szöveg az oldalon. Ha ezt a kettőt jól eltalálja, az API többi része már csak variációk egy témára. Itt van az egész, egy konzolprogram, amely egyetlen oldalt ír, közel tucatnyi nyelven üdvözölve az olvasót:

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.

A HotPDF komponens által Delphi-ben készített többnyelvű Hello World PDF

Ez a teljes példa. A try/finally ... Free párossal ellátott THotPDF.Create(nil) a szokásos Delphi tulajdonosi (ownership) minta, és a PDF ezen nem változtat. Ami figyelmet érdemel, az a belső négy lépésből álló gerinc: tulajdonságok beállítása, BeginDoc, rajzolás, EndDoc. A sorrend nem felcserélhető

Dokumentumtulajdonságok beállítása a BeginDoc előtt

A BeginDoc az a pillanat, amikor a HotPDF rögzíti a dokumentum szerkezetét, így bármit, ami a teljes fájlt érinti, ezelőtt kell beállítani. A Compression := cmFlateDecode bekapcsolja a FlateDecode tömörítést a tartalomfolyamoknál (content streams), ami a különbséget jelenti egy kompakt és egy feleslegesen felfújt fájl között. A FontEmbedding := True bepakolja a fájlba azt a betűtípust, amellyel rajzol, így ugyanúgy fog kinézni egy olyan gépen, amelyre soha nem telepítették az Arial Unicode MS-t, mint az Önén. Ha bármelyiket a BeginDoc után rendeli hozzá, az csendben semmit sem tesz a már folyamatban lévő dokumentummal, és hiba sem figyelmezteti Önt

SetFont, majd TextOut, és figyeljen az origóra

Két dolog a rajzolási hívásokkal kapcsolatban mindenkit meglep az első oldalán. Az első a sorrend: a SetFont-nak le kell futnia minden olyan TextOut előtt, amely függ tőle, és meg kell ismételni minden AddPage után, mert az aktuális betűtípus nem éli túl az oldaltörést (page break). A második a koordináta-rendszer. A TextOut az oldal bal alsó sarkától mér, nem a bal felsőtől, az Y pedig felfelé haladva növekszik, pontokban (1/72 hüvelyk). Ezért haladnak itt a sorok lefelé 760-tól, mindegyik 30 ponttal az előző alatt. Bárki, aki a képernyőgrafika felől érkezik, az ellenkezőjét feltételezi, és az első sort egyenesen az alsó peremen (bottom edge) kívülre írja

Egy betűtípus, sok írásmód

Az ok, amiért egyetlen SetFont hordozni tud latint, cirillt, japánt és kínait ugyanazon az oldalon, maga a betűkészlet: az Arial Unicode MS szinte minden írásmód (script) glifáit (glyphs) egyetlen fájlba csomagolja. A SetFont negyedik argumentuma a Windows karakterkészlet, és a DEFAULT_CHARSET átadása lehetővé teszi, hogy a rendszer karakterlánconként (string) válasszon glifákat, ahelyett, hogy mindent egy régi kódlaphoz (code page) rögzítene. Két kikötés jár ezzel a kényelemmel. A betűtípusnak jelen kell lennie a PDF-et készítő gépen, mert a HotPDF azt ágyazza be, amire az operációs rendszer a nevet feloldja; ha az Arial Unicode MS hiányzik, a Windows csendben beletesz egy helyettesítőt, és a CJK szövege üres dobozokként jelenhet meg. És nem fed le egyenlően minden írásmódot: az olyan jobbról balra (right-to-left) tartó írásokhoz, mint az arab és a héber, vagy bármihez, ami komplex alakítást (shaping) igényel, egy dedikált, a RegisterUnicodeTTF segítségével betöltött betűtípushoz és a jobbról balra tartó szöveghívásokhoz kell nyúlnia, ami egy külön téma

Futtassa le, és megkapja a HelloWorld.pdf-et a munkakönyvtárban: egyetlen oldal, néhány sor többnyelvű szöveg, tömörítve, beágyazott betűtípussal. A kézenfekvő következő lépések a szöveg méretének, stílusának és forgatásának beállítása, valamint egynél több blokkjának szándékos elhelyezése, amelyeket a TextOut példa mind végigvesz. Ha szöveg helyett vonalakat (rules), dobozokat és képeket szeretne rajzolni, ugyanaz az oldalobjektum tartalmazza ezeket a hívásokat is

A TextOut, a SetFont és az itt bemutatott dokumentumhívások a HotPDF Component részét képezik Delphi-hez és C++Builder-hez