Artículo técnico

Delphi HotPDF Hello World: Su primer programa en PDF

Toda biblioteca de PDF incluye un "hello world" (hola mundo), y vale la pena detenerse en el de HotPDF, porque el programa más pequeño que hace algo ya fuerza dos decisiones que usted repetirá en todos los documentos posteriores: qué fuente establecer y en qué parte de la página se ubica el texto. Acierte en esas dos y el resto de la API es variaciones sobre el mismo 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.

Multilingual Hello World PDF produced by the HotPDF component in Delphi

Ese es todo el ejemplo. El THotPDF.Create(nil) emparejado con try/finally ... Free es el patrón de propiedad habitual de Delphi, y el PDF no lo cambia. Lo que merece atención es la estructura de cuatro pasos en el interior: 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 consolida la estructura del documento, por lo que todo lo que afecte al archivo completo debe establecerse antes. Compression := cmFlateDecode activa FlateDecode para los flujos de contenido, lo cual es la diferencia entre un archivo compacto y uno innecesariamente inflado. FontEmbedding := True empaqueta la fuente con la que dibuja en el archivo, de modo que se ve igual en una computadora que nunca ha tenido Arial Unicode MS instalado que en la suya. Asigne cualquiera de las dos después de BeginDoc y no hará nada silenciosamente al documento que ya está en progreso, sin ningún error que le advierta

SetFont, luego TextOut y observe el origen

Dos cosas sobre las llamadas de dibujo atrapan a todos en su primera página. La primera es el orden: SetFont tiene que ejecutarse antes de cualquier TextOut que dependa de ella, y tiene que repetirse después de cada AddPage, porque la fuente actual no sobrevive a un salto de página. La segunda es el sistema de coordenadas. TextOut se mide desde la esquina inferior izquierda de la página, no desde la superior izquierda, con Y aumentando a medida que se desplaza hacia arriba, en puntos (1/72 de pulgada). Es por eso que las líneas aquí marchan hacia abajo desde 760, cada una 30 puntos por debajo de la última. Cualquiera que provenga de los gráficos de pantalla asume lo contrario y escribe la primera línea directamente fuera del borde inferior

Una fuente, muchas escrituras

La razón por la que una sola SetFont puede contener caracteres latinos, cirílicos, japoneses y chinos en la misma página es la fuente en sí: Arial Unicode MS agrupa glifos para casi todas las escrituras en un solo archivo. El cuarto argumento para SetFont es el conjunto de caracteres de Windows, y pasar DEFAULT_CHARSET permite que el sistema elija glifos por cadena en lugar de fijar todo a una página de códigos heredada. Dos advertencias acompañan a esa conveniencia. La fuente tiene que estar presente en la computadora que construye el PDF, porque HotPDF incrusta lo que sea que el sistema operativo resuelva para el nombre; si falta Arial Unicode MS, Windows introduce silenciosamente un sustituto y su texto CJK puede aparecer como cuadros vacíos. Y no cubre todas las escrituras por igual: para escritura de derecha a izquierda como el árabe y el hebreo, o cualquier cosa que necesite un modelado complejo, usted recurre a una fuente dedicada cargada con RegisterUnicodeTTF y las llamadas de texto de derecha a izquierda, lo cual es un tema en sí mismo

Ejecútelo y obtendrá HelloWorld.pdf en el directorio de trabajo: una página, unas pocas líneas de texto multilingüe, comprimido, con la fuente incrustada. Los siguientes pasos obvios son darle a ese texto tamaño, estilo y rotación, y colocar más de un bloque del mismo deliberadamente, ambas cosas que se analizan en el ejemplo TextOut. Cuando usted desee dibujar reglas, cuadros e imágenes en lugar de solo texto, el mismo objeto de página también contiene esas llamadas

Las llamadas TextOut, SetFont y de documento que se muestran aquí son parte del HotPDF Component para Delphi y C++Builder