Toda biblioteca PDF incluye un «hello world», y el de HotPDF merece la pena examinarlo con detenimiento, porque el programa más pequeño que hace algo ya obliga a tomar dos decisiones que repetiréis en todos los documentos posteriores: qué fuente establecer y dónde aterriza el texto en la página. Si acertáis en esas dos, el resto de la API son variaciones sobre un tema. Aquí está todo, un programa de consola que escribe una sola página saludando al lector en casi una docena de idiomas:
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.

Eso es todo el ejemplo. El THotPDF.Create(nil) emparejado con try/finally ... Free es el patrón de gestión de recursos habitual en Delphi, y PDF no lo cambia. Lo que merece atención es la columna vertebral de cuatro pasos que hay dentro: establecer propiedades, BeginDoc, dibujar, EndDoc. El orden no es intercambiable.
Establecer las propiedades del documento antes de BeginDoc
BeginDoc es el momento en que HotPDF fija la estructura del documento, por lo que cualquier cosa que afecte al fichero completo debe establecerse antes de llamarlo. Compression := cmFlateDecode activa FlateDecode para los flujos de contenido, lo que marca la diferencia entre un fichero compacto y uno innecesariamente voluminoso. FontEmbedding := True incrusta en el fichero la fuente con la que se dibuja, de modo que el documento tiene el mismo aspecto en una máquina que nunca haya tenido instalado Arial Unicode MS que en la vuestra. Si asignáis cualquiera de los dos después de BeginDoc, el cambio no tiene ningún efecto sobre el documento en curso, sin que ningún error lo avise.
SetFont, luego TextOut, y atención al origen de coordenadas
Hay dos cosas sobre las llamadas de dibujo que sorprenden a todo el mundo en la primera página. La primera es el orden: SetFont debe ejecutarse antes de cualquier TextOut que dependa de él, y debe repetirse después de cada AddPage, porque la fuente activa no sobrevive a un salto de página. La segunda es el sistema de coordenadas. TextOut mide desde la esquina inferior izquierda de la página, no desde la superior izquierda, con Y creciendo al moverse hacia arriba, en puntos (1/72 de pulgada). Por eso las líneas descienden desde 760, cada una 30 puntos por debajo de la anterior. Quien llega desde gráficos de pantalla asume lo contrario y escribe la primera línea fuera del borde inferior.
Una fuente, muchos sistemas de escritura
La razón por la que un único SetFont puede abarcar latín, cirílico, japonés y chino en la misma página es la propia tipografía: Arial Unicode MS agrupa glifos de casi todos los sistemas de escritura en un solo fichero. El cuarto argumento de SetFont es el juego de caracteres de Windows, y pasar DEFAULT_CHARSET permite que el sistema elija los glifos por cadena en lugar de anclar todo a una página de códigos heredada. Con esa comodidad vienen dos advertencias. La fuente debe estar presente en la máquina que genera el PDF, porque HotPDF incrusta lo que el sistema operativo resuelva para ese nombre; si Arial Unicode MS no está instalada, Windows sustituye silenciosamente por otra fuente y el texto CJK puede aparecer como cuadros vacíos. Además, no cubre todos los sistemas de escritura por igual: para la escritura de derecha a izquierda como el árabe o el hebreo, o para cualquier cosa que requiera un modelado complejo, se recurre a una fuente dedicada cargada con RegisterUnicodeTTF y las llamadas de texto de derecha a izquierda, que es un tema aparte.
Al ejecutarlo se obtiene HelloWorld.pdf en el directorio de trabajo: una página, unas pocas líneas de texto multilingüe, comprimidas, con la fuente incrustada. Los pasos siguientes más obvios son dar a ese texto tamaño, estilo y rotación, y colocar deliberadamente más de un bloque, cuestiones ambas que el ejemplo de TextOut desarrolla en detalle. Cuando se quiere dibujar reglas, cajas e imágenes en lugar de solo texto, el mismo objeto de página contiene esas llamadas.
Las llamadas TextOut, SetFont y de documento mostradas aquí forman parte del HotPDF Component para Delphi y C++Builder.