Teknisk artikel

Delphi HotPDF Hello World: Dit første PDF-program

Ethvert PDF-bibliotek leverer et "hello world," og HotPDF's er værd at dvæle ved, fordi det mindste program, der gør noget, allerede tvinger to beslutninger, du vil gentage i hvert efterfølgende dokument: hvilken skrifttype der skal indstilles, og hvor på siden teksten lander. Få de to rigtigt, og resten af API'et er variationer over et tema. Her er det hele, et konsolprogram, der skriver en enkelt side, der hilser læseren på næsten et dusin sprog:

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

Det er hele eksemplet. THotPDF.Create(nil) parret med try/finally ... Free er det ordinære Delphi-ejerskabsmønster, og PDF ændrer det ikke. Det, der fortjener opmærksomhed, er de fire trin indeni: indstil egenskaber, BeginDoc, tegn, EndDoc. Rækkefølgen er ikke udskiftelig

Indstil dokumentegenskaber før BeginDoc

BeginDoc er det øjeblik, HotPDF binder dokumentets struktur, så alt, der påvirker hele filen, skal indstilles inden. Compression := cmFlateDecode slår FlateDecode til for indholdsstrømmene, hvilket er forskellen mellem en kompakt fil og en unødigt oppustet. FontEmbedding := True pakker den skrifttype, du tegner med, ind i filen, så den ser ens ud på en maskine, der aldrig har haft Arial Unicode MS installeret. Tildel en af dem efter BeginDoc, og det gør stiltiende ingenting ved dokumentet, der allerede er i gang, uden nogen fejl til at advare dig

SetFont, dernæst TextOut, og hold øje med origo

To ting ved tegnekalder fanger alle på deres første side. Den første er rækkefølgen: SetFont skal køre inden enhver TextOut, der afhænger af den, og den skal gentages efter hver AddPage, fordi den aktuelle skrifttype ikke overlever et sideskift. Den anden er koordinatsystemet. TextOut måler fra sidens nederste venstre hjørne, ikke øverste venstre, med Y stigende opad, i punkter (1/72 tomme). Det er grunden til, at linjerne her marcherer nedad fra 760, hver 30 punkter under den forrige. Alle, der kommer fra skærmgrafik, antager det modsatte og skriver den første linje direkte ud over den nedre kant

Én skrifttype, mange skriftsystemer

Grunden til, at en enkelt SetFont kan håndtere latinsk, kyrillisk, japansk og kinesisk på samme side, er selve skrifttypen: Arial Unicode MS samler tegn for næsten hvert skriftsystem i én fil. Det fjerde argument til SetFont er Windows-tegnsættet, og at sende DEFAULT_CHARSET lader systemet vælge tegn pr. streng i stedet for at fastlåse alt til én gammel kode-side. To forbehold følger med den bekvemmelighed. Skrifttypen skal være til stede på den maskine, der bygger PDF'en, fordi HotPDF indlejrer det, som OS'et opløser navnet til; hvis Arial Unicode MS mangler, bytter Windows stiltiende med en erstatning, og din CJK-tekst kan komme ud som tomme felter. Og den dækker ikke hvert skriftsystem lige godt: for højre-mod-venstre-skrift som arabisk og hebraisk, eller noget der kræver kompleks formning, bruger man en dedikeret skrifttype indlæst med RegisterUnicodeTTF og højre-mod-venstre-tekstkaldene, hvilket er et emne for sig selv

Kør det, og du får HelloWorld.pdf i arbejdskataloget: én side, et par linjer flersproget tekst, komprimeret, med skrifttypen indlejret. De oplagte næste skridt er at give teksten størrelse, stil og rotation, og placere mere end én blok af den bevidst, begge dele som TextOut-eksemplet gennemgår. Når du vil tegne linjer, bokse og billeder frem for blot tekst, indeholder det samme sideobjekt også disse kald

TextOut-, SetFont- og dokumentkaldene vist her er en del af HotPDF-komponenten til Delphi og C++Builder