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:

Diagram over HotPDF Hello World-programflowets fire kald i Delphi med PDF-origo nederst til venstre og to lydløse fælder fremhævet
Create, begin, draw, end er hele rygraden, og nederst-til-venstre-origo forklarer, hvorfor senere linjer bruger mindre Y-værdier
program HelloWorld;

{$APPTYPE CONSOLE}

uses
  Winapi.Windows,   // til DEFAULT_CHARSET; på Delphi før XE2 brug bare Windows
  HPDFDoc;          // HotPDF-hovedunit

procedure CreateHelloWorld(const FileName: string);
var
  Pdf: THotPDF;
begin
  Pdf := THotPDF.Create(nil);
  try
    Pdf.FileName := FileName;
    Pdf.Compression := cmFlateDecode;   // krymp content streams
    Pdf.FontEmbedding := True;          // embed fonten, så den renderer alle steder
    Pdf.BeginDoc;

    // Én font der dækker mange skriftsystemer. 4. argument er Windows-charset;
    // DEFAULT_CHARSET lader systemet vælge glyffer per streng
    Pdf.CurrentPage.SetFont('Arial Unicode MS', [], 14, DEFAULT_CHARSET);

    // TextOut måler fra NEDERSTE VENSTRE hjørne, i points, med Y voksende opad
    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.

Flersproget Hello World PDF produceret af HotPDF Delphi-komponenten i 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-Delphi-komponenten til Delphi og C++Builder