Technical Article

Delphi HotPDF Hello World: jūsų pirmoji PDF programa

Kiekviena PDF biblioteka pateikia „hello world“ pavyzdį, o HotPDF pavyzdį verta panagrinėti išsamiau. Net ir mažiausia veikianti programa reikalauja priimti du sprendimus, kuriuos kartosite kurdami kiekvieną dokumentą: kokį šriftą nustatyti ir kurioje puslapio vietoje išvesti tekstą. Teisingai atlikus šiuos du žingsnius, visa kita API tėra tos pačios temos variacijos. Štai visa konsolės programa, kuri sukuria vieną puslapį ir pasveikina skaitytoją beveik dešimčia kalbų:

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.

Daugiakalbis „Hello World“ PDF failas, sukurtas naudojant HotPDF komponentą Delphi

Tai yra visas pavyzdys. Konstruktorius THotPDF.Create(nil) kartu su try/finally ... Free bloku atspindi įprastą objektų valdymo šabloną Delphi aplinkoje, ir PDF čia nieko nekeičia. Vertėtų atkreipti dėmesį į vidinę keturių žingsnių struktūrą: savybių nustatymas, BeginDoc, piešimas, EndDoc. Šios sekos keisti negalima.

Dokumento savybių nustatymas prieš BeginDoc

BeginDoc yra akimirka, kai HotPDF patvirtina dokumento struktūrą, todėl visi nustatymai, turintys įtakos visam failui, turi būti nurodyti prieš jį. Compression := cmFlateDecode įjungia „FlateDecode“ turinio srautams, o tai lemia skirtumą tarp kompaktiško failo ir be reikalo padidinto failo. FontEmbedding := True įtraukia šriftą į failą, todėl dokumentas atrodys taip pat ir kompiuteryje, kuriame nėra įdiegtas „Arial Unicode MS“ šriftas. Priskyrus bet kurią iš šių savybių po BeginDoc iškvietimo, jos tiesiog neturės jokios įtakos jau kuriamam dokumentui ir nebus pateikta jokia klaida, kuri apie tai įspėtų.

SetFont, tada TextOut ir koordinačių pradžios taškas

Du dalykai, susiję su piešimo iškvietimais, dažniausiai klaidina pradedančiuosius. Pirmasis yra tvarka: SetFont turi būti paleistas prieš bet kurį nuo jo priklausomą TextOut, be to, jį reikia iškviesti po kiekvieno AddPage, nes dabartinis šriftas neišsaugomas perėjus į naują puslapį. Antrasis dalykas – koordinačių sistema. TextOut matuoja nuo apatinio kairiojo puslapio kampo, o ne nuo viršutinio kairiojo, o Y koordinatė didėja judant aukštyn taškais (1/72 colio). Štai kodėl čia esančios eilutės eina žemyn nuo 760 taško, o kiekviena kita eilutė yra 30 taškų žemiau už ankstesnę. Kūrėjai, pratę prie ekrano grafikos koordinačių, dažnai daro priešingą prielaidą ir pirmąją eilutę išveda tiesiai už apatinės ekrano ribos.

Vienas šriftas, daug raštų

Priežastis, kodėl vienas SetFont iškvietimas gali apdoroti lotyniškus, kirilicos, japonų ir kinų raštus tame pačiame puslapyje, yra pats šriftas: „Arial Unicode MS“ sujungia beveik visų raštų glifus į vieną failą. Ketvirtasis SetFont argumentas yra „Windows“ simbolių rinkinys (charset), o perduodant DEFAULT_CHARSET sistema leidžia parinkti glifus pagal konkrečią eilutę, užuot prisirišus prie vieno pasenusio kodavimo puslapio. Tačiau su šiuo patogumu susiję du niuansai. Šriftas turi būti įdiegtas mašinoje, kurioje kurimas PDF, nes HotPDF įterpia tai, ką operacinė sistema susieja su nurodytu pavadinimu. Jei „Arial Unicode MS“ nėra, „Windows“ tyliai pakeis jį kitu šriftu, o jūsų CJK tekstas gali būti atvaizduotas kaip tušti kvadratėliai. Be to, šis šriftas neapima visų raštų vienodai: rašymui iš dešinės į kairę (pavyzdžiui, arabų ar hebrajų kalboms) arba tekstams, kuriems reikalingas sudėtingas formavimas (shaping), reikės naudoti tam skirtą šriftą, įkeltą per RegisterUnicodeTTF, ir iškvietimus, skirtus tekstui iš dešinės į kairę, o tai yra atskira tema.

Paleidę programą, darbiniame kataloge gausite failą HelloWorld.pdf: vienas puslapis, kelios daugiakalbio teksto eilutės, suglaudintas ir su įterptu šriftu. Kiti logiški žingsniai būtų nustatyti šio teksto dydį, stilių ir pasukimą bei tikslingai išdėstyti kelis teksto blokus. Abu šie aspektai išsamiai aptariami TextOut pavyzdyje. Kai norėsite piešti linijas, stačiakampius ar paveikslėlius, o ne tik tekstą, visi šie iškvietimai bus atliekami tame pačiame puslapio objekte.

Čia parodyti TextOut, SetFont ir kiti dokumento iškvietimai yra HotPDF Component, skirto Delphi ir C++Builder, dalis.