Technisch artikel

Delphi HotPDF Hello World: Uw Eerste PDF Programma

Elke PDF-bibliotheek wordt geleverd met een "hello world", en het is de moeite waard om even stil te staan bij die van HotPDF. Het kleinste programma dat überhaupt iets doet, dwingt al twee beslissingen af die u in elk document daarna zult herhalen: welk lettertype u moet instellen en waar op de pagina de tekst terechtkomt. Doe die twee goed en de rest van de API is variaties op een thema. Hier is het in zijn geheel, een consoleprogramma dat een enkele pagina schrijft die de lezer begroet in bijna een dozijn talen:

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. De THotPDF.Create(nil) gecombineerd met try/finally ... Free is het gewone eigendomspatroon van Delphi, en PDF verandert dat niet. Wat aandacht verdient is de ruggengraat van vier stappen binnenin: eigenschappen instellen, BeginDoc, tekenen, EndDoc. De volgorde is niet inwisselbaar

Documenteigenschappen instellen vóór BeginDoc

BeginDoc is het moment waarop HotPDF de structuur van het document vastlegt, dus alles wat het hele bestand beïnvloedt, moet daaraan voorafgaand worden ingesteld. Compression := cmFlateDecode schakelt FlateDecode in voor de inhoudsstromen, wat het verschil is tussen een compact bestand en een onnodig opgeblazen bestand. FontEmbedding := True verpakt het lettertype waarmee u tekent in het bestand, zodat het er op een machine waarop Arial Unicode MS nooit is geïnstalleerd, hetzelfde uitziet als op de uwe. Wijs één van beide toe na BeginDoc en het doet stilletjes niets met het reeds lopende document, zonder een foutmelding om u te waarschuwen

SetFont, dan TextOut, en let op de oorsprong

Twee dingen over de tekenaanroepen vallen iedereen op bij hun eerste pagina. Het eerste is de volgorde: SetFont moet worden uitgevoerd vóór elke TextOut die ervan afhangt, en het moet worden herhaald na elke AddPage, omdat het huidige lettertype een pagina-einde niet overleeft. Het tweede is het coördinatensysteem. TextOut meet vanaf de linkerbenedenhoek van de pagina, niet van linksboven, waarbij Y toeneemt naarmate u omhoog gaat, in punten (1/72 inch). Dat is de reden waarom de lijnen hier naar beneden marcheren vanaf 760, elk 30 punten onder de vorige. Iedereen die van schermgrafieken komt, neemt het tegenovergestelde aan en schrijft de eerste regel rechtstreeks buiten de onderrand

Eén lettertype, vele scripts

De reden dat een enkele SetFont Latijns, Cyrillisch, Japans en Chinees op dezelfde pagina kan dragen, is het lettertype zelf: Arial Unicode MS bundelt glyphs voor bijna elk script in één bestand. Het vierde argument voor SetFont is de Windows tekenset, en het doorgeven van DEFAULT_CHARSET laat het systeem glyphs per string kiezen in plaats van alles vast te pinnen op één verouderde codepagina. Twee kanttekeningen gaan gepaard met dat gemak. Het lettertype moet aanwezig zijn op de machine die de PDF bouwt, omdat HotPDF embedt waarnaar het besturingssysteem de naam herleidt; als Arial Unicode MS ontbreekt, wisselt Windows stilletjes een vervanger in en kan uw CJK-tekst eruitzien als lege vierkantjes. En het dekt niet elk script gelijkmatig: voor schrijven van rechts naar links, zoals Arabisch en Hebreeuws, of iets dat complexe vorming vereist, grijpt u naar een speciaal lettertype geladen met RegisterUnicodeTTF en de tekstaanroepen van rechts naar links, wat een onderwerp op zich is

Voer het uit en u krijgt HelloWorld.pdf in de werkmap: één pagina, een paar regels meertalige tekst, gecomprimeerd, met het lettertype ingesloten. De voor de hand liggende volgende stappen zijn het geven van die tekstgrootte, stijl en rotatie, en het weloverwogen plaatsen van meer dan één blok ervan, die beide in het TextOut voorbeeld worden doorgenomen. Wanneer u regels, vakken en afbeeldingen in plaats van alleen tekst wilt tekenen, bevat hetzelfde paginaobject ook die aanroepen

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