Un code-barres n'est pas une image avec laquelle vous décorez un document. C'est une mesure, et le scanner est l'instrument qui la lit. Ce recadrage décide de presque tout sur la façon dont vous devez en dessiner un dans un PDF. Les barres ne véhiculent aucune information par leur noirceur ; l'information réside dans le rapport entre la largeur des barres et la largeur des espaces, et un lecteur la récupère en chronométrant les transitions lorsqu'un laser ou un capteur le balaye. Compressez cette géométrie, floutez-la ou encombrez ses marges, et vous produisez quelque chose qui ressemble exactement à un code-barres et qui se scanne comme une tache (smudge). HotPDF vous donne deux façons d'en placer un sur une page, et la différence entre elles est précisément la différence entre contrôler cette géométrie et l'abandonner

Ce que HotPDF peut encoder
HotPDF dessine des symbologies linéaires (unidimensionnelles), et l'ensemble est plus vaste que ce dont la plupart des projets ont besoin. L'énumération THPDFBarcodeType couvre la famille du Code 2 parmi 5 sous ses formes entrelacées (interleaved), industrielles et matricielles ; le Code 39 et sa variante étendue ; les trois sous-ensembles du Code 128 (A, B et C) ; le Code 93 simple et étendu ; MSI ; PostNet ; Codabar ; le groupe de vente au détail UPC et EAN, à savoir EAN-8, EAN-13, UPC-A, les UPC-E0 et UPC-E1 compressés, et les suppléments UPC à 2 et 5 chiffres ; et les sous-ensembles GS1-128 (EAN-128). C'est suffisant pour couvrir les étiquettes de la chaîne d'approvisionnement, les points de vente au détail et les anciens codes industriels encore en service dans les entrepôts
Ce qu'il ne dessine pas, c'est la famille bidimensionnelle. Il n'y a pas de QR, Data Matrix ou PDF417 ici. Ceux-ci encodent des octets dans une grille avec leurs propres mathématiques de correction d'erreurs, et si une exigence nomme l'un d'eux, ce n'est pas le bon outil et vous devez le savoir avant de construire autour plutôt qu'après. Pour les codes unidimensionnels, la question pratique est plus étroite : quelle symbologie accepte les données que vous possédez réellement, car les encodages ne sont pas interchangeables
Les contraintes de données sont réelles et elles mordent au moment de la génération. Les variantes du Code 2 parmi 5 et le MSI n'acceptent que des chiffres. Le Code 39 transporte des lettres majuscules, des chiffres et une poignée de signes de ponctuation ; si vous avez besoin de minuscules ou de la plage ASCII complète, c'est le Code 39 étendu (Code 39 Extended) ou un sous-ensemble du Code 128 qu'il vous faut. Le Code 128C regroupe deux chiffres dans chaque symbole pour plus de densité, il veut donc une chaîne numérique de longueur paire et rien d'autre. EAN-13 attend douze chiffres et calcule le treizième comme contrôle (check) ; EAN-8 en attend sept et calcule le huitième ; UPC-A en prend douze. Si vous remettez à une symbologie des données qu'elle ne peut pas représenter, vous n'obtenez pas d'exception utile, vous obtenez un code-barres qui encode des données indésirables (garbage), ce qui est pire, car il semble parfait jusqu'à ce que quelqu'un le scanne à une caisse
Deux chemins de dessin, deux niveaux de contrôle
La méthode à privilégier en production est DrawBarcode, sur l'objet page. Elle prend la symbologie, une position, une hauteur et un paramètre qui compte plus que le reste : MUnit, la largeur du module. Le module est la largeur de la barre la plus étroite, l'atome dont toutes les autres mesures du code sont un multiple, et il est exprimé ici en points. Tout ce qui détermine si le résultat imprimé est lisible remonte à ce seul nombre entier
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;
Deux arguments méritent un examen plus approfondi. UseCheckSum ajoute le chiffre de contrôle modulo-10 attendu par la symbologie, et pour les codes de vente au détail, vous le voulez presque toujours à True ; désactivez-le uniquement lorsque vos données comportent déjà un contrôle précalculé, sinon vous obtiendrez un chiffre doublé. Les couleurs des barres et du fond (background) sont les deux derniers paramètres, et la tentation d'y être créatif est un piège abordé ci-dessous. Notez également l'origine des coordonnées : comme tout autre appel de dessin dans HotPDF, les valeurs X et Y mesurent depuis le coin inférieur gauche de la page en points, avec un Y qui augmente vers le haut, la même convention que celle détaillée dans l'exemple Hello World
Le deuxième chemin est DirectDrawBarcode, qui prend les données et une boîte englobante (bounding box), X, Y, Width, Height, et met à l'échelle le motif de la barre pour remplir cette largeur. C'est pratique pour disposer des codes sur une grille parce que vous nommez l'empreinte et la méthode y adapte les barres. Cette commodité est aussi son danger. Lorsque vous lui donnez une largeur, vous ne définissez plus la taille du module ; la méthode divise l'espace que vous accordez par le nombre de barres dont les données ont besoin, et la barre la plus étroite devient tout ce qui ressort de cette division. Demandez une chaîne Code 128 dense dans une boîte trop étroite et les modules rétrécissent silencieusement en dessous de ce que n'importe quel scanner peut résoudre. Pour tout ce qui doit être scanné de manière fiable, préférez DrawBarcode et définissez MUnit délibérément. Réservez DirectDrawBarcode pour les aperçus et pour les arrangements où vous avez mesuré que les barres résultantes restent lisibles
La largeur du module est une décision de résolution
Voici l'arithmétique qui détermine si votre étiquette fonctionne. Un scanner laser et un appareil photo ont tous deux une plus petite caractéristique qu'ils peuvent distinguer, et la barre étroite doit se trouver confortablement au-dessus de celle-ci après l'impression. Le plancher largement cité pour les codes linéaires à usage général est une barre étroite de 13 mil, soit environ 0,33 mm, et de nombreux guides de vente au détail et industriels traitent cela comme un minimum plutôt que comme une cible. Traduisez cela en unités PDF : un point correspond à 1/72 de pouce, soit environ 0,353 mm, de sorte qu'un seul point de largeur de module se situe juste à ce plancher. C'est pourquoi MUnit := 1 est la plus petite valeur à laquelle vous devriez faire confiance pour un code destiné à un vrai scanner, et pourquoi le doubler à 2 achète une marge qui ne coûte presque rien sur une étiquette avec de la place à revendre
Connectez maintenant cela à la résolution de sortie, car le module doit également survivre à l'imprimante. Sur une imprimante laser 300 DPI, un point d'appareil (device dot) correspond à 1/300 de pouce, un module d'un point équivaut donc à environ quatre points de large. Quatre points sont à peine suffisants pour rendre un bord net ; la propagation du toner et une légère erreur de repérage le grignotent, et la barre qui mesurait un point dans votre PDF s'imprime plus grosse ou plus fine que ne le permettent les spécifications. Passez le module à 2 points et vous avez huit points avec lesquels travailler, ce qui absorbe ce bruit. La règle qui vaut la peine d'être intériorisée : la largeur du module que vous définissez en points doit correspondre à un nombre entier et confortable de points d'appareil à votre résolution d'impression réelle, et non à la résolution que vous souhaiteriez avoir. Un code qui se scanne parfaitement sur l'écran et qui échoue sur l'imprimante de l'entrepôt a presque toujours échoué à cette vérification
La zone de silence (quiet zone) fait partie du symbole
La raison la plus courante pour laquelle un code-barres correctement encodé ne sera pas scanné est la zone de silence, la marge vierge de chaque côté des barres. Les scanners utilisent ce vide pour trouver où le code commence et se termine ; sans elle, le lecteur ne peut pas distinguer la première barre de ce qui se trouve à côté d'elle sur la page. Les normes sont spécifiques. La plupart des symbologies linéaires exigent une zone de silence d'au moins dix fois la largeur du module de chaque côté, et les codes de vente au détail UPC et EAN requièrent neuf modules à gauche et sept à droite. Avec un module d'un point, cela correspond à peu près à dix points, soit environ un septième de pouce, d'espace blanc garanti flanquant les barres
HotPDF dessine les barres et rien d'autre. Il ne réserve pas la zone de silence pour vous, ce qui signifie que la responsabilité est la vôtre et qu'il est facile de l'oublier. Le mode de défaillance est subtil : vous placez un code-barres au ras de la bordure de la cellule d'un tableau, ou vous laissez la mise en page (page layout) entasser un logo à côté de celui-ci, et le code qui a passé tous les tests sur une page blanche cesse d'être scanné au moment où il est expédié dans un document réel. Budgétisez la marge de manière explicite. Avant d'appeler DrawBarcode, laissez au moins dix largeurs de module d'espace libre des deux côtés, et traitez tout graphique, règle ou texte qui s'immisce dans cette bande comme un défaut, et non comme un choix esthétique
Couleur, contraste et la ligne lisible par l'homme
Les couleurs des barres et du fond existent pour que vous puissiez correspondre à une palette de marque, et elles sont le moyen le plus rapide de casser un code fonctionnel. Les scanners lisent le contraste, classiquement avec de la lumière rouge, et ils s'attendent à des barres sombres sur un champ clair. Noir sur blanc est la seule combinaison que vous devriez utiliser sans tester. Bleu foncé ou vert foncé sur blanc peut passer ; tout ce qui a un faible contraste de luminance, et en particulier les barres rouges, qu'un scanner à lumière rouge voit comme un arrière-plan, ne fonctionnera pas. Si un designer demande des codes-barres colorés, la réponse honnête est que les barres restent noires et que la couleur va ailleurs sur l'étiquette
Le chemin DrawBarcode peut également rendre le texte lisible par l'homme sous les barres, les chiffres qu'un commis (clerk) saisit lorsqu'un balayage échoue. Ce texte est une solution de repli (fallback), et non une décoration, donc lorsque vous placez votre propre légende, gardez-la à l'écart de la zone de silence ; une étiquette de la symbologie entassée dans la marge latérale détruit le même espace vide dont dépend le scanner. Les champs de l'exemple ici, y compris TextOut pour toutes les étiquettes environnantes, sont les mêmes appels de dessin couverts dans le guide de sortie de rapport (report output guide), qui est l'endroit où aller lorsque le code-barres est un élément dans une page composée plus grande
Une courte habitude de vérification
Les barres vectorielles (Vector bars) sont un avantage qui mérite d'être nommé. Étant donné que DrawBarcode écrit le code sous forme d'opérateurs de dessin PDF plutôt que d'image pixellisée (rasterized), les barres restent nettes à n'importe quel zoom et le fichier ne possède aucune résolution propre ; la seule résolution qui compte est celle de l'imprimante. Cela ne vous dispense pas de tester, cela signifie simplement que le test doit avoir lieu sur papier. Générez un échantillon, imprimez-le sur l'appareil à la résolution la plus basse que vos codes rencontreront réellement, et scannez-le avec la même classe de lecteur que vos utilisateurs détiennent, et non avec l'imageur haut de gamme de votre bureau. Vérifiez les zones de silence avec une règle sur l'impression, confirmez que la largeur du module a survécu au passage des points (points) aux points d'impression (dots), et vérifiez que la valeur décodée correspond à ce que vous avez encodé, y compris le chiffre de contrôle. Cinq minutes avec un vrai scanner permettent de détecter tous les échecs décrits ci-dessus, et elles les détectent avant qu'une palette de stock mal étiquetée ne le fasse
Les méthodes DrawBarcode et DirectDrawBarcode présentées ici font partie du Composant HotPDF pour Delphi et C++Builder