File: code128.c

package info (click to toggle)
pdfio 1.5.1%2Bdfsg-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 9,860 kB
  • sloc: ansic: 20,581; sh: 3,300; makefile: 239
file content (208 lines) | stat: -rw-r--r-- 6,013 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
//
// 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;			// 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 B
  static const char code128_start_code_c = '\315';
					// Start code C
  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 = pdfioFileCreateFontObjFromBase(pdf, "Helvetica");

  // 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...
  pdfioContentSetFillColorGray(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*/false, text);
    pdfioContentTextEnd(page_st);
  }

  pdfioStreamClose(page_st);

  // Close and return...
  pdfioFileClose(pdf);

  return (0);
}