-
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2ecb9cf
commit eb9dad9
Showing
3 changed files
with
211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// | ||
// Code 128 barcode example for PDFio. | ||
// | ||
// Copyright © 2024 by Michael R Sweet. | ||
// | ||
// Licensed under Apache License v2.0. See the file "LICENSE" for more | ||
// information. | ||
// | ||
// Usage: | ||
// | ||
// ./code128 "BARCODE" ["TEXT"] >FILENAME.pdf | ||
// | ||
|
||
#include <pdfio.h> | ||
#include <pdfio-content.h> | ||
|
||
|
||
// | ||
// 'make_code128()' - Make a Code 128 barcode string. | ||
// | ||
// This function produces a Code B (printable ASCII) representation of the | ||
// source string and doesn't try to optimize using Code C. Non-printable and | ||
// extended characters are ignored in the source string. | ||
// | ||
|
||
|
||
static char * // O - Output string | ||
make_code128(char *dst, // I - Destination buffer | ||
const char *src, // I - Source string | ||
size_t dstsize) // I - Size of destination buffer | ||
{ | ||
char *dstptr, // Pointer into destination buffer | ||
*dstend; // End of destination buffer | ||
int sum = 0; // Weighted sum | ||
static const char *code128_chars = // Code 128 characters | ||
" !\"#$%&'()*+,-./0123456789:;<=>?" | ||
"@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_" | ||
"`abcdefghijklmnopqrstuvwxyz{|}~\303" | ||
"\304\305\306\307\310\311\312"; | ||
static const char code128_fnc_3 = '\304'; | ||
// FNC 3 | ||
static const char code128_fnc_2 = '\305'; | ||
// FNC 2 | ||
static const char code128_shift_b = '\306'; | ||
// Shift B (for lowercase) | ||
static const char code128_code_c = '\307'; | ||
// Code C | ||
static const char code128_code_b = '\310'; | ||
// Code B | ||
static const char code128_fnc_4 = '\311'; | ||
// FNC 4 | ||
static const char code128_fnc_1 = '\312'; | ||
// FNC 1 | ||
static const char code128_start_code_a = '\313'; | ||
// Start code A | ||
static const char code128_start_code_b = '\314'; | ||
// Start code A | ||
static const char code128_start_code_c = '\315'; | ||
// Start code A | ||
static const char code128_stop = '\316'; | ||
// Stop pattern | ||
|
||
|
||
// Start a Code B barcode... | ||
dstptr = dst; | ||
dstend = dst + dstsize - 3; | ||
|
||
*dstptr++ = code128_start_code_b; | ||
sum = code128_start_code_b - 100; | ||
|
||
while (*src && dstptr < dstend) | ||
{ | ||
if (*src >= ' ' && *src < 0x7f) | ||
{ | ||
sum += (dstptr - dst) * (*src - ' '); | ||
*dstptr++ = *src; | ||
} | ||
|
||
src ++; | ||
} | ||
|
||
// Add the weighted sum modulo 103 | ||
*dstptr++ = code128_chars[sum % 103]; | ||
|
||
// Add the stop pattern and return... | ||
*dstptr++ = code128_stop; | ||
*dstptr = '\0'; | ||
|
||
return (dst); | ||
} | ||
|
||
|
||
// | ||
// 'output_cb()' - Write PDF data to the standard output... | ||
// | ||
|
||
static ssize_t // O - Number of bytes written | ||
output_cb(void *output_cbdata, // I - Callback data (not used) | ||
const void *buffer, // I - Buffer to write | ||
size_t bytes) // I - Number of bytes to write | ||
{ | ||
(void)output_cbdata; | ||
|
||
return ((ssize_t)fwrite(buffer, 1, bytes, stdout)); | ||
} | ||
|
||
|
||
// | ||
// 'main()' - Produce a single-page barcode file. | ||
// | ||
|
||
int // O - Exit status | ||
main(int argc, // I - Number of command-line arguments | ||
char *argv[]) // I - Command-line arguments | ||
{ | ||
const char *barcode, // Barcode to show | ||
*text; // Text to display under barcode | ||
pdfio_file_t *pdf; // Output PDF file | ||
pdfio_obj_t *barcode_font; // Barcode font object | ||
pdfio_obj_t *text_font = NULL; // Text font object | ||
pdfio_dict_t *page_dict; // Page dictionary | ||
pdfio_rect_t media_box; // Media/CropBox for page | ||
pdfio_stream_t *page_st; // Page stream | ||
char barcode_temp[256]; // Barcode buffer | ||
double barcode_height = 36.0, // Height of barcode | ||
barcode_width, // Width of barcode | ||
text_height = 0.0, // Height of text | ||
text_width = 0.0; // Width of text | ||
|
||
|
||
// Get the barcode and optional text from the command-line... | ||
if (argc < 2 || argc > 3) | ||
{ | ||
fputs("Usage: code128 \"BARCODE\" [\"TEXT\"] >FILENAME.pdf\n", stderr); | ||
return (1); | ||
} | ||
|
||
barcode = argv[1]; | ||
text = argv[2]; | ||
|
||
// Output a PDF file to the standard output... | ||
#ifdef _WIN32 | ||
setmode(1, O_BINARY); // Force binary output on Windows | ||
#endif // _WIN32 | ||
|
||
if ((pdf = pdfioFileCreateOutput(output_cb, /*output_cbdata*/NULL, /*version*/NULL, /*media_box*/NULL, /*crop_box*/NULL, /*error_cb*/NULL, /*error_data*/NULL)) == NULL) | ||
return (1); | ||
|
||
// Load fonts... | ||
barcode_font = pdfioFileCreateFontObjFromFile(pdf, "code128.ttf", /*unicode*/false); | ||
if (text) | ||
text_font = pdfioFileCreateFontObjFromFile(pdf, "../testfiles/OpenSans-Regular.ttf", /*unicode*/true); | ||
|
||
// Generate Code128 characters for the desired barcode... | ||
if (!(barcode[0] & 0x80)) | ||
barcode = make_code128(barcode_temp, barcode, sizeof(barcode_temp)); | ||
|
||
// Compute sizes of the text... | ||
barcode_width = pdfioContentTextMeasure(barcode_font, barcode, barcode_height); | ||
if (text && text_font) | ||
{ | ||
text_height = 9.0; | ||
text_width = pdfioContentTextMeasure(text_font, text, text_height); | ||
} | ||
|
||
// Compute the size of the PDF page... | ||
media_box.x1 = 0.0; | ||
media_box.y1 = 0.0; | ||
media_box.x2 = (barcode_width > text_width ? barcode_width : text_width) + 18.0; | ||
media_box.y2 = barcode_height + text_height + 18.0; | ||
|
||
// Start a page for the barcode... | ||
page_dict = pdfioDictCreate(pdf); | ||
|
||
pdfioDictSetRect(page_dict, "MediaBox", &media_box); | ||
pdfioDictSetRect(page_dict, "CropBox", &media_box); | ||
|
||
pdfioPageDictAddFont(page_dict, "B128", barcode_font); | ||
if (text_font) | ||
pdfioPageDictAddFont(page_dict, "TEXT", text_font); | ||
|
||
page_st = pdfioFileCreatePage(pdf, page_dict); | ||
|
||
// Draw the page... | ||
pdfioContentSetStrokeColorGray(page_st, 0.0); | ||
|
||
pdfioContentSetTextFont(page_st, "B128", barcode_height); | ||
pdfioContentTextBegin(page_st); | ||
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - barcode_width), 9.0 + text_height); | ||
pdfioContentTextShow(page_st, /*unicode*/false, barcode); | ||
pdfioContentTextEnd(page_st); | ||
|
||
if (text && text_font) | ||
{ | ||
pdfioContentSetTextFont(page_st, "TEXT", text_height); | ||
pdfioContentTextBegin(page_st); | ||
pdfioContentTextMoveTo(page_st, 0.5 * (media_box.x2 - text_width), 9.0); | ||
pdfioContentTextShow(page_st, /*unicode*/true, text); | ||
pdfioContentTextEnd(page_st); | ||
} | ||
|
||
pdfioStreamClose(page_st); | ||
|
||
// Close and return... | ||
pdfioFileClose(pdf); | ||
|
||
return (0); | ||
} | ||
|
Binary file not shown.