Um código de barras não é uma imagem com a qual você decora um documento. Ele é uma medida, e o scanner é o instrumento que o lê. Essa reformulação decide quase tudo sobre como você deve desenhar um em um PDF. As barras não carregam informações pela sua escuridão; a informação vive na proporção entre as larguras das barras e as larguras dos espaços, e um leitor as recupera cronometrando as transições à medida que um laser ou sensor varre a área. Comprima essa geometria, borre-a ou lote suas margens, e você produzirá algo que parece exatamente com um código de barras e será escaneado como um borrão. O HotPDF oferece duas maneiras de colocá-lo em uma página, e a diferença entre elas é precisamente a diferença entre controlar essa geometria e abrir mão dela

O que o HotPDF pode codificar
O HotPDF desenha simbologias lineares (unidimensionais), e o conjunto é mais amplo do que a maioria dos projetos necessita. A enumeração THPDFBarcodeType abrange a família Code 2 de 5 em suas formas intercalada, industrial e matricial; Code 39 e sua variante estendida; os três subconjuntos A, B e C do Code 128; Code 93 simples e estendido; MSI; PostNet; Codabar; o grupo de varejo UPC e EAN, a saber, EAN-8, EAN-13, UPC-A, os comprimidos UPC-E0 e UPC-E1, e os complementos UPC de 2 e 5 dígitos; e os subconjuntos GS1-128 (EAN-128). Isso é suficiente para cobrir etiquetas de cadeia de suprimentos, ponto de venda de varejo e os códigos industriais mais antigos que ainda sobrevivem em armazéns
O que ele não desenha é a família bidimensional. Não há QR, Data Matrix ou PDF417 aqui. Esses codificam bytes em uma grade com sua própria matemática de correção de erros, e se um requisito nomear um deles, esta é a ferramenta errada e você deve saber disso antes de construir em torno dela, em vez de depois. Para códigos unidimensionais, a questão prática é mais estreita: qual simbologia aceita os dados que você realmente tem, porque as codificações não são intercambiáveis
As restrições de dados são reais e elas pesam no momento da geração. As variantes do Code 2 de 5 e o MSI aceitam apenas dígitos. O Code 39 carrega letras maiúsculas, dígitos e um punhado de sinais de pontuação; se você precisar de letras minúsculas ou da faixa ASCII completa, isso é Code 39 Extended ou um subconjunto do Code 128. O Code 128C agrupa dois dígitos em cada símbolo por densidade, então ele requer uma string numérica de comprimento par e nada mais. O EAN-13 espera doze dígitos e calcula o décimo terceiro como verificação; o EAN-8 espera sete e calcula o oitavo; o UPC-A aceita doze. Forneça a uma simbologia dados que ela não pode representar e você não obterá uma exceção útil, você obterá um código de barras que codifica lixo, o que é pior, porque parece bom até que alguém o escaneie em um caixa
Dois caminhos de desenho, dois níveis de controle
O método a ser procurado em produção é DrawBarcode, no objeto da página. Ele recebe a simbologia, uma posição, uma altura e um parâmetro que importa mais do que o resto: MUnit, a largura do módulo. O módulo é a largura da barra mais estreita, o átomo do qual todas as outras medidas no código são múltiplas, e é expresso aqui em pontos (points). Tudo sobre se o resultado impresso é escaneável remonta a esse único inteiro
var
Pdf: THotPDF;
begin
Pdf := THotPDF.Create(nil);
try
Pdf.FileName := 'label.pdf';
Pdf.BeginDoc;
// BCType, X, Y, Height, MUnit (module width in points), angle,
// data, UseCheckSum, bar color, background color.
Pdf.CurrentPage.DrawBarcode(
bcCodeEAN13, // symbology
72, 680, // X, Y in points from the bottom-left
60, // bar height
1, // MUnit: 1pt narrowest bar
0, // no rotation
'123456789012', // 12 digits; the 13th is the check
True, // append the modulo-10 check digit
clBlack, clWhite); // bars black, background white
Pdf.EndDoc;
finally
Pdf.Free;
end;
end;
Dois argumentos merecem um olhar mais atento. UseCheckSum anexa o dígito verificador módulo 10 que a simbologia espera, e para os códigos de varejo você quase sempre vai querer como True; desligue-o apenas quando seus dados já contiverem uma verificação pré-calculada, ou você obterá um dígito duplicado. As cores da barra e do fundo são os dois últimos parâmetros, e a tentação de ser criativo aí é uma armadilha discutida abaixo. Observe também a origem da coordenada: como qualquer outra chamada de desenho no HotPDF, o X e Y medem a partir do canto inferior esquerdo da página em pontos, com Y crescendo para cima, a mesma convenção que o exemplo Hello World percorre
O segundo caminho é o DirectDrawBarcode, que pega os dados e uma caixa delimitadora, X, Y, Width, Height, e dimensiona o padrão de barras para preencher essa largura. É conveniente para dispor códigos em uma grade porque você nomeia a pegada e o método ajusta as barras a ela. Essa conveniência também é o seu perigo. Quando você dá a ela uma largura, não está mais definindo o tamanho do módulo; o método divide qualquer espaço que você permitir entre a quantidade de barras de que os dados precisam, e a barra mais estreita se torna o que quer que resulte dessa divisão. Peça por uma string densa de Code 128 dentro de uma caixa muito estreita e os módulos encolherão abaixo do que qualquer scanner pode resolver, silenciosamente. Para qualquer coisa que precise ser escaneada com segurança, prefira o DrawBarcode e defina o MUnit deliberadamente. Reserve o DirectDrawBarcode para visualizações e para arranjos em que você mediu que as barras resultantes permanecem legíveis
A largura do módulo é uma decisão de resolução
Aqui está a aritmética que determina se a sua etiqueta funciona. Um scanner a laser e uma câmera têm o menor recurso que podem distinguir, e a barra estreita deve aterrissar confortavelmente acima dele após a impressão. O limite inferior amplamente citado para códigos lineares de uso geral é uma barra estreita de 13 mil (milésimos de polegada), cerca de 0,33 mm, e muitos guias de varejo e industriais tratam isso como um mínimo em vez de um alvo. Traduza isso em unidades PDF: um ponto (point) é 1/72 de polegada, cerca de 0,353 mm, de modo que um único ponto de largura do módulo fica exatamente nesse limite. É por isso que MUnit := 1 é o menor valor em que você deve confiar para um código destinado a um scanner real, e por que dobrá-lo para 2 compra uma margem que não custa quase nada em uma etiqueta com espaço de sobra
Agora conecte isso à resolução de saída, porque o módulo também deve sobreviver à impressora. Em uma impressora a laser de 300 DPI, um ponto de dispositivo (dot) é 1/300 de polegada, então um módulo de um ponto (point) tem cerca de quatro pontos de dispositivo (dots) de largura. Quatro pontos de dispositivo mal são suficientes para renderizar uma borda limpa; o espalhamento de toner e pequenos erros de registro o corroem, e a barra que media um ponto (point) em seu PDF é impressa mais gorda ou mais fina do que a especificação permite. Aumente o módulo para 2 pontos e você terá oito pontos de dispositivo para trabalhar, o que absorve esse ruído. A regra que vale a pena internalizar: a largura do módulo que você define em pontos deve ser mapeada para um número inteiro e confortável de pontos de dispositivo (dots) em sua resolução de impressão real, não a resolução que você gostaria de ter. Um código que é escaneado perfeitamente da tela e falha na impressora do armazém quase sempre falhou nessa verificação
A zona de silêncio é parte do símbolo
A razão mais comum pela qual um código de barras codificado corretamente não será escaneado é a zona de silêncio, a margem em branco de cada lado das barras. Os scanners usam esse vazio para descobrir onde o código começa e termina; sem ele, o leitor não consegue distinguir a primeira barra de qualquer coisa que esteja ao lado dela na página. Os padrões são específicos. A maioria das simbologias lineares requer uma zona de silêncio de pelo menos dez vezes a largura do módulo de cada lado, e os códigos de varejo UPC e EAN pedem nove módulos à esquerda e sete à direita. Com um módulo de um ponto, isso é cerca de dez pontos, cerca de um sétimo de polegada, de espaço em branco garantido flanqueando as barras
O HotPDF desenha as barras e nada mais. Ele não reserva a zona de silêncio para você, o que significa que a responsabilidade é sua e é fácil de esquecer. O modo de falha é sutil: você coloca um código de barras alinhado com a borda da célula de uma tabela ou deixa que o layout da página esprema um logotipo ao lado dele, e o código que passou em todos os testes em uma página em branco para de ser lido no momento em que é enviado dentro de um documento real. Estipule o orçamento da margem explicitamente. Antes de chamar DrawBarcode, deixe pelo menos dez larguras de módulo de espaço livre em ambos os lados e trate qualquer gráfico, régua ou texto que invada essa faixa como um defeito, não uma escolha cosmética
Cor, contraste e a linha legível por humanos
As cores da barra e do fundo existem para que você possa combiná-las com a paleta de uma marca, e elas são a maneira mais rápida de quebrar um código funcional. Os scanners leem o contraste, classicamente com luz vermelha, e esperam barras escuras em um campo claro. Preto no branco é a única combinação que você deve escolher sem testar. Azul escuro ou verde escuro no branco podem passar; qualquer coisa com contraste de luminância baixo e, em particular, barras vermelhas, que um scanner de luz vermelha vê como fundo, não passarão. Se um designer pedir códigos de barras coloridos, a resposta honesta é que as barras continuam pretas e a cor vai para outro lugar na etiqueta
O caminho do DrawBarcode também pode renderizar o texto legível por humanos abaixo das barras, os dígitos que um balconista digita quando uma varredura falha. Esse texto é um substituto, não uma decoração, portanto, ao colocar sua própria legenda, mantenha-a longe da zona de silêncio; um rótulo da simbologia espremido na margem lateral anula o mesmo espaço em branco do qual o scanner depende. Os campos no exemplo aqui, incluindo o TextOut para quaisquer rótulos ao redor, são as mesmas chamadas de desenho abordadas no guia de saída de relatório, que é o lugar a ir quando o código de barras é um elemento em uma página composta maior
Um pequeno hábito de verificação
Barras vetoriais são uma vantagem que vale a pena mencionar. Como DrawBarcode escreve o código como operadores de desenho de PDF, em vez de uma imagem rasterizada, as barras permanecem nítidas em qualquer zoom e o arquivo não carrega nenhuma resolução própria; a única resolução que importa é a da impressora. Isso não isenta você de testar, significa apenas que o teste deve acontecer no papel. Gere uma amostra, imprima-a no dispositivo de resolução mais baixa com o qual seus códigos realmente se encontrarão e digitalize-a com a mesma classe de leitor que seus usuários possuem, e não com o leitor de última geração em sua mesa. Verifique as zonas de silêncio com uma régua na impressão, confirme que a largura do módulo sobreviveu à viagem de pontos para pontos de dispositivo (dots) e verifique se o valor decodificado corresponde ao que você codificou, incluindo o dígito verificador. Cinco minutos com um scanner real evitam todas as falhas descritas acima, e as detectam antes de um palete de estoque etiquetado incorretamente o faça
Os métodos DrawBarcode e DirectDrawBarcode mostrados aqui fazem parte do HotPDF Component para Delphi e C++Builder