Technisch artikel

Delphi HotPDF Hello World: Uw eerste PDF-programma

Elke PDF-bibliotheek wordt geleverd met een "hello world," en die van HotPDF is de moeite waard om even rustig bij stil te staan, omdat het kleinste programma dat iets doet al twee beslissingen afdwingt die u in elk volgend document zult herhalen: welk lettertype u instelt en waar de tekst op de pagina terechtkomt. Zet die twee goed neer en de rest van de API is variaties op een thema. Hier is het volledige programma, een consoleprogramma dat één pagina schrijft waarop de lezer in bijna een dozijn talen wordt begroet:

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.

Meertalige Hello World-PDF geproduceerd door de HotPDF-component in Delphi

Dat is het volledige voorbeeld. Het patroon THotPDF.Create(nil) gecombineerd met try/finally ... Free is het gangbare Delphi-eigendomspatroon, en PDF verandert dat niet. Wat aandacht verdient is de vierledige ruggengraat binnenin: eigenschappen instellen, BeginDoc, tekenen, EndDoc. De volgorde is niet verwisselbaar.

Documenteigenschappen instellen vóór BeginDoc

BeginDoc is het moment waarop HotPDF de structuur van het document vastlegt, dus alles wat het gehele bestand beïnvloedt moet daarvóór worden ingesteld. Compression := cmFlateDecode schakelt FlateDecode in voor de inhoudsstromen, wat het verschil maakt tussen een compact bestand en een onnodig opgeblazen bestand. FontEmbedding := True pakt het lettertype waarmee u tekent in het bestand, zodat het er op een machine zonder Arial Unicode MS hetzelfde uitziet als op de uwe. Wijs een van beide toe na BeginDoc en het heeft stilzwijgend geen effect op het document dat al in uitvoering is, zonder foutmelding.

SetFont, dan TextOut, en let op de oorsprong

Twee dingen aan de tekenaanroepen vangen iedereen op hun eerste pagina. Het eerste is de volgorde: SetFont moet worden uitgevoerd vóór elke TextOut die ervan afhankelijk is, en moet worden herhaald na elke AddPage, omdat het huidige lettertype een pagina-einde niet overleeft. Het tweede is het coördinatenstelsel. TextOut meet vanuit de linkeronderhoek van de pagina, niet de linkerbovenhoek, met Y dat toeneemt naarmate u omhoog gaat, in punten (1/72 inch). Dat is waarom de regels hier omlaag lopen vanaf 760, elke 30 punten lager dan de vorige. Wie gewend is aan schermgraphics gaat uit van het tegenovergestelde en schrijft de eerste regel direct buiten de onderrand.

Één lettertype, vele schriftsoorten

De reden waarom één SetFont-aanroep Latijn, Cyrillisch, Japans en Chinees op dezelfde pagina kan weergeven is het lettertype zelf: Arial Unicode MS bundelt glyphs voor bijna elk schrift in één bestand. Het vierde argument van SetFont is de Windows-tekenset, en het doorgeven van DEFAULT_CHARSET laat het systeem glyphs per tekenreeks kiezen in plaats van alles aan één verouderde codepagina te koppelen. Twee kanttekeningen horen bij dat gemak. Het lettertype moet aanwezig zijn op de machine die de PDF aanmaakt, omdat HotPDF insluit wat het besturingssysteem bij de naam opzoekt; als Arial Unicode MS ontbreekt, vervangt Windows het stilzwijgend door een alternatief en kan uw CJK-tekst als lege vakjes verschijnen. En het dekt niet elk schrift even goed: voor rechts-naar-links schrift zoals Arabisch en Hebreeuws, of voor alles wat complexe opmaak vereist, gebruikt u een speciaal lettertype dat geladen is via RegisterUnicodeTTF en de rechts-naar-links-tekstaanroepen, wat een apart onderwerp is.

Voer het programma uit en u krijgt HelloWorld.pdf in de werkmap: één pagina, enkele regels meertalige tekst, gecomprimeerd, met het lettertype ingesloten. De voor de hand liggende volgende stappen zijn die tekst voorzien van een grootte, stijl en rotatie, en er meer dan één blok van bewust plaatsen, die beide worden behandeld in het TextOut-voorbeeld. Als u lijnen, kaders en afbeeldingen wilt tekenen in plaats van alleen tekst, bevat hetzelfde paginaobject ook die aanroepen.

De hier getoonde aanroepen TextOut, SetFont en de documentaanroepen maken deel uit van de HotPDF Component voor Delphi en C++Builder.