Artigo Técnico

Delphi HotPDF Hello World: Seu Primeiro Programa PDF

Toda biblioteca de PDF vem com um "hello world", e vale a pena ir mais devagar no do HotPDF, porque o menor programa que faz qualquer coisa já força duas decisões que você repetirá em todos os documentos depois: qual fonte definir e em que lugar da página o texto fica. Acerte essas duas coisas e o restante da API será variações de um tema. Aqui está a coisa toda, um programa de console que grava uma única página saudando o leitor em quase uma dúzia 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.

Hello World PDF multilíngue produzido pelo componente HotPDF em Delphi

Esse é o exemplo inteiro. O THotPDF.Create(nil) emparelhado com o try/finally ... Free é o padrão comum de propriedade do Delphi, e o PDF não o altera. O que merece atenção é a espinha dorsal de quatro etapas em seu interior: definir as propriedades, BeginDoc, desenhar, EndDoc. A ordem não é intercambiável

Definir propriedades do documento antes do BeginDoc

BeginDoc é o momento em que o HotPDF confirma a estrutura do documento, portanto, tudo o que afeta todo o arquivo deve ser definido antes dele. Compression := cmFlateDecode ativa o FlateDecode para os fluxos de conteúdo, o que é a diferença entre um arquivo compacto e um desnecessariamente inchado. FontEmbedding := True empacota a fonte com a qual você desenha no arquivo, de modo que ele tenha a mesma aparência em uma máquina que nunca teve a Arial Unicode MS instalada e na sua. Atribua qualquer um deles após o BeginDoc e ele silenciosamente não fará nada no documento já em andamento, sem nenhum erro para avisá-lo

SetFont, em seguida TextOut, e preste atenção na origem

Duas coisas sobre as chamadas de desenho pegam todo mundo na primeira página. A primeira é a ordem: SetFont deve ser executado antes de qualquer TextOut que dependa dele, e deve ser repetido após cada AddPage, porque a fonte atual não sobrevive a uma quebra de página. O segundo é o sistema de coordenadas. TextOut mede a partir do canto inferior esquerdo da página, não do canto superior esquerdo, e o Y aumenta à medida que você se move para cima, em pontos (1/72 de polegada). É por isso que as linhas aqui marcham para baixo a partir do 760, cada uma 30 pontos abaixo da última. Quem vem dos gráficos de tela presume o oposto e escreve a primeira linha direto na borda inferior

Uma fonte, muitos scripts

O motivo pelo qual uma única SetFont pode conter latim, cirílico, japonês e chinês na mesma página é o próprio tipo de letra: Arial Unicode MS agrupa glifos para quase todos os scripts em um único arquivo. O quarto argumento de SetFont é o conjunto de caracteres do Windows, e a passagem de DEFAULT_CHARSET permite que o sistema escolha glifos por sequência de caracteres em vez de fixar tudo em uma página de códigos herdada. Duas ressalvas acompanham essa conveniência. A fonte tem que estar presente na máquina que compila o PDF, porque o HotPDF incorpora o que quer que o sistema operacional resolva o nome; se a Arial Unicode MS estiver faltando, o Windows discretamente colocará um substituto e seu texto CJK poderá sair como caixas vazias. E isso não abrange todos os scripts da mesma forma: para a escrita da direita para a esquerda, como o árabe e o hebraico, ou para qualquer coisa que precise de formas complexas, você busca uma fonte dedicada, carregada com o RegisterUnicodeTTF e as chamadas de texto da direita para a esquerda, o que é um tópico à parte

Execute-o e você obterá HelloWorld.pdf no diretório de trabalho: uma página, algumas linhas de texto multilíngue, compactado e com a fonte incorporada. As próximas etapas óbvias são dar a esse texto tamanho, estilo e rotação, e colocar deliberadamente mais de um bloco dele, ambas as coisas que o exemplo TextOut faz. Quando você deseja desenhar regras, caixas e imagens em vez de apenas texto, o mesmo objeto de página também mantém essas chamadas

As chamadas TextOut, SetFont e o documento mostrados aqui fazem parte do Componente HotPDF para Delphi e C++Builder