multi_encoder 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,200 @@
1
+ /*
2
+ * pcl.c -- printing the "partial" bar encoding in PCL format
3
+ *
4
+ * Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org)
5
+ * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
6
+ * Copyright (c) 2001 Andrea Scopece (a.scopece@tin.it)
7
+ *
8
+ * This program is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version.
12
+ *
13
+ * This program is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
21
+ */
22
+
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+ #include <string.h>
26
+ #include <ctype.h>
27
+ #include <errno.h>
28
+
29
+ #include "barcode.h"
30
+
31
+ #define SHRINK_AMOUNT 0.15 /* shrink the bars to account for ink spreading */
32
+
33
+
34
+ /*
35
+ * How do the "partial" and "textinfo" strings work? See file "ps.c"
36
+ */
37
+
38
+
39
+ int Barcode_pcl_print(struct Barcode_Item *bc, FILE *f)
40
+ {
41
+ int i, j, k, barlen;
42
+ double f1, f2, fsav=0;
43
+ int mode = '-'; /* text below bars */
44
+ double scalef=1, xpos, x0, y0, yr;
45
+ unsigned char *ptr;
46
+ unsigned char c;
47
+
48
+ char font_id[6]; /* default font, should be "scalable" */
49
+ /* 0 Line printer, use on older LJet II, isn't scalable */
50
+ /* 4148 Univers, use on LJet III series, and Lj 4L, 5L */
51
+ /* 16602 Arial, default LJ family 4, 5, 6, Color, Djet */
52
+
53
+ if (!bc->partial || !bc->textinfo) {
54
+ bc->error = EINVAL;
55
+ return -1;
56
+ }
57
+
58
+ /*
59
+ * Maybe this first part can be made common to several printing back-ends,
60
+ * we'll see how that works when other ouput engines are added
61
+ */
62
+
63
+ /* First, calculate barlen */
64
+ barlen = bc->partial[0] - '0';
65
+ for (ptr = bc->partial+1; *ptr; ptr++)
66
+ if (isdigit(*ptr))
67
+ barlen += (*ptr - '0');
68
+ else if (islower(*ptr))
69
+ barlen += (*ptr - 'a'+1);
70
+
71
+ /* The scale factor depends on bar length */
72
+ if (!bc->scalef) {
73
+ if (!bc->width) bc->width = barlen; /* default */
74
+ scalef = bc->scalef = (double)bc->width / (double)barlen;
75
+ }
76
+
77
+ /* The width defaults to "just enough" */
78
+ if (!bc->width) bc->width = barlen * scalef +1;
79
+
80
+ /* But it can be too small, in this case enlarge and center the area */
81
+ if (bc->width < barlen * scalef) {
82
+ int wid = barlen * scalef + 1;
83
+ bc->xoff -= (wid - bc->width)/2 ;
84
+ bc->width = wid;
85
+ /* Can't extend too far on the left */
86
+ if (bc->xoff < 0) {
87
+ bc->width += -bc->xoff;
88
+ bc->xoff = 0;
89
+ }
90
+ }
91
+
92
+ /* The height defaults to 80 points (rescaled) */
93
+ if (!bc->height) bc->height = 80 * scalef;
94
+
95
+ #if 0
96
+ /* If too small (5 + text), enlarge and center */
97
+ i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
98
+ if (bc->height < i * scalef ) {
99
+ int hei = i * scalef;
100
+ bc->yoff -= (hei-bc->height)/2;
101
+ bc->height = hei;
102
+ if (bc->yoff < 0) {
103
+ bc->height += -bc->yoff;
104
+ bc->yoff = 0;
105
+ }
106
+ }
107
+ #else
108
+ /* If too small (5 + text), reduce the scale factor and center */
109
+ i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
110
+ if (bc->height < i * scalef ) {
111
+ double scaleg = ((double)bc->height) / i;
112
+ int wid = bc->width * scaleg / scalef;
113
+ bc->xoff += (bc->width - wid)/2;
114
+ bc->width = wid;
115
+ scalef = scaleg;
116
+ }
117
+ #endif
118
+
119
+ /*
120
+ * deal with PCL output
121
+ */
122
+
123
+ xpos = bc->margin + (bc->partial[0]-'0') * scalef;
124
+ for (ptr = bc->partial+1, i=1; *ptr; ptr++, i++) {
125
+ /* special cases: '+' and '-' */
126
+ if (*ptr == '+' || *ptr == '-') {
127
+ mode = *ptr; /* don't count it */ i++; continue;
128
+ }
129
+
130
+ /* j is the width of this bar/space */
131
+ if (isdigit (*ptr)) j = *ptr-'0';
132
+ else j = *ptr-'a'+1;
133
+ if (i%2) { /* bar */
134
+ x0 = bc->xoff + xpos;
135
+ y0 = bc->yoff + bc->margin;
136
+ yr = bc->height;
137
+ if (!(bc->flags & BARCODE_NO_ASCII)) { /* leave space for text */
138
+ if (mode == '-') {
139
+ /* text below bars: 10 points or five points */
140
+ yr -= (isdigit(*ptr) ? 10 : 5) * scalef;
141
+ } else { /* '+' */
142
+ /* text above bars: 10 or 0 from bottom, and 10 from top */
143
+ y0 += (isdigit(*ptr) ? 10 : 0) * scalef;
144
+ yr -= (isdigit(*ptr) ? 20 : 10) * scalef;
145
+ }
146
+ }
147
+
148
+ fprintf(f,"%c&a%.0fH", 27, x0 * 10.0);
149
+ fprintf(f,"%c&a%.0fV", 27, y0 * 10.0);
150
+ fprintf(f,"%c*c%.0fH", 27, ((j*scalef)-SHRINK_AMOUNT) * 10.0);
151
+ fprintf(f,"%c*c%.0fV", 27, yr * 10.0);
152
+ fprintf(f,"%c*c0P\n", 27);
153
+ }
154
+ xpos += j * scalef;
155
+ }
156
+
157
+ /* the text */
158
+
159
+ mode = '-'; /* reinstantiate default */
160
+ if (!(bc->flags & BARCODE_NO_ASCII)) {
161
+ k=0; /* k is the "previous font size" */
162
+ for (ptr = bc->textinfo; ptr; ptr = strchr(ptr, ' ')) {
163
+ while (*ptr == ' ') ptr++;
164
+ if (!*ptr) break;
165
+ if (*ptr == '+' || *ptr == '-') {
166
+ mode = *ptr; continue;
167
+ }
168
+ if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) {
169
+ fprintf(stderr, "barcode: impossible data: %s\n", ptr);
170
+ continue;
171
+ }
172
+
173
+ /* select a Scalable Font */
174
+
175
+ if (fsav != f2)
176
+ {
177
+ if ((bc->flags & BARCODE_OUT_PCL_III) == BARCODE_OUT_PCL_III)
178
+ { strcpy(font_id, "4148"); /* font Univers */
179
+ }
180
+ else
181
+ { strcpy(font_id, "16602"); /* font Arial */
182
+ }
183
+
184
+ fprintf(f,"%c(8U%c(s1p%5.2fv0s0b%sT", 27, 27, f2 * scalef, font_id);
185
+ }
186
+ fsav = f2;
187
+
188
+ fprintf(f,"%c&a%.0fH", 27, (bc->xoff + f1 * scalef + bc->margin) * 10.0);
189
+ fprintf(f,"%c&a%.0fV", 27,
190
+ mode != '-'
191
+ ? ((double)bc->yoff + bc->margin + 8*scalef) * 10.0
192
+ : ((double)bc->yoff + bc->margin + bc->height ) * 10.0);
193
+
194
+ fprintf(f, "%c", c);
195
+ }
196
+
197
+ }
198
+
199
+ return 0;
200
+ }
@@ -0,0 +1,164 @@
1
+ /*
2
+ * plessey.c -- encoding for Plessey
3
+ *
4
+ * Copyright (c) 2000 Leonid A. Broukhis (leob@mailcom.com)
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19
+ */
20
+
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+ #include <string.h>
24
+ #include <ctype.h>
25
+ #include <errno.h>
26
+
27
+ #include "barcode.h"
28
+
29
+ static char * patterns[] = { "13", "31" };
30
+
31
+ /* this is ordered in decades to simplify encoding */
32
+ static char alphabet[] =
33
+ "0123456789" "ABCDEF";
34
+
35
+ /* stop sequence may be 231311313 (barcodemill.com) */
36
+ static char *fillers[] = { "031311331", "331311313" };
37
+
38
+ static int width = 16, startpos = 16;
39
+
40
+ /*
41
+ * Check that the text can be encoded. Returns 0 or -1.
42
+ * If it's all lowecase convert to uppercase and accept it
43
+ */
44
+ int Barcode_pls_verify(unsigned char *text)
45
+ {
46
+ int i, upper = 0, lower = 0;
47
+
48
+ if (!strlen(text))
49
+ return -1;
50
+ for (i=0; text[i]; i++) {
51
+ if (!strchr(alphabet,toupper(text[i])))
52
+ return -1;
53
+ if (isupper(text[i])) upper++;
54
+ if (islower(text[i])) lower++;
55
+ }
56
+ if (upper && lower)
57
+ return -1;
58
+ return 0;
59
+ }
60
+
61
+ static int add_one(char *ptr, int code)
62
+ {
63
+ sprintf(ptr, "%s%s%s%s",
64
+ patterns[code & 1],
65
+ patterns[(code >> 1) & 1],
66
+ patterns[(code >> 2) & 1],
67
+ patterns[(code >> 3) & 1]
68
+ );
69
+ return 0;
70
+ }
71
+
72
+ /*
73
+ * The encoding functions fills the "partial" and "textinfo" fields.
74
+ * Lowercase chars are converted to uppercase
75
+ */
76
+ int Barcode_pls_encode(struct Barcode_Item *bc)
77
+ {
78
+ static char *text;
79
+ static char *partial; /* dynamic */
80
+ static char *textinfo; /* dynamic */
81
+ char *c, *ptr, *textptr;
82
+ unsigned char *checkptr;
83
+ int i, code, textpos;
84
+ static char check[9] = {1,1,1,1,0,1,0,0,1};
85
+ if (bc->partial)
86
+ free(bc->partial);
87
+ if (bc->textinfo)
88
+ free(bc->textinfo);
89
+ bc->partial = bc->textinfo = NULL; /* safe */
90
+
91
+ if (!bc->encoding)
92
+ bc->encoding = strdup("plessey");
93
+
94
+ text = bc->ascii;
95
+ if (!text) {
96
+ bc->error = EINVAL;
97
+ return -1;
98
+ }
99
+ /* the partial code is 8 * (head + text + check + tail) + margin + term. */
100
+ partial = malloc( (strlen(text) + 4) * 8 + 3);
101
+ checkptr = calloc (1, strlen(text) * 4 + 8);
102
+
103
+ if (!partial || !checkptr) {
104
+ if (partial) free(partial);
105
+ if (checkptr) free(checkptr);
106
+ bc->error = errno;
107
+ return -1;
108
+ }
109
+
110
+ /* the text information is at most "nnn:fff:c " * strlen +term */
111
+ textinfo = malloc(10*strlen(text) + 2);
112
+ if (!textinfo) {
113
+ bc->error = errno;
114
+ free(partial);
115
+ return -1;
116
+ }
117
+
118
+ strcpy(partial, fillers[0]);
119
+ ptr = partial + strlen(partial);
120
+ textptr = textinfo;
121
+ textpos = startpos;
122
+
123
+ for (i=0; i<strlen(text); i++) {
124
+ c = strchr(alphabet, toupper(text[i]));
125
+ if (!c) {
126
+ bc->error = EINVAL; /* impossible if text is verified */
127
+ free(partial);
128
+ free(textinfo);
129
+ return -1;
130
+ }
131
+ code = c - alphabet;
132
+ add_one(ptr, code);
133
+ sprintf(textptr, "%i:12:%c ", textpos, toupper(text[i]));
134
+
135
+ textpos += width; /* width of each code */
136
+ textptr += strlen(textptr);
137
+ ptr += strlen(ptr);
138
+ checkptr[4*i] = code & 1;
139
+ checkptr[4*i+1] = (code >> 1) & 1;
140
+ checkptr[4*i+2] = (code >> 2) & 1;
141
+ checkptr[4*i+3] = (code >> 3) & 1;
142
+ }
143
+ /* The CRC checksum is required */
144
+ for (i=0; i < 4*strlen(text); i++) {
145
+ int j;
146
+ if (checkptr[i])
147
+ for (j = 0; j < 9; j++)
148
+ checkptr[i+j] ^= check[j];
149
+ }
150
+ for (i = 0; i < 8; i++) {
151
+ sprintf(ptr, patterns[checkptr[strlen(text) * 4 + i]]);
152
+ ptr += 2;
153
+ }
154
+ fprintf(stderr, "CRC: ");
155
+ for (i = 0; i < 8; i++) {
156
+ fputc('0' + checkptr[strlen(text) * 4 + i], stderr);
157
+ }
158
+ fputc('\n', stderr);
159
+ strcpy(ptr, fillers[1]);
160
+ bc->partial = partial;
161
+ bc->textinfo = textinfo;
162
+
163
+ return 0;
164
+ }
@@ -0,0 +1,272 @@
1
+ /*
2
+ * ps.c -- printing the "partial" bar encoding
3
+ *
4
+ * Copyright (c) 1999 Alessandro Rubini (rubini@gnu.org)
5
+ * Copyright (c) 1999 Prosa Srl. (prosa@prosa.it)
6
+ *
7
+ * This program is free software; you can redistribute it and/or modify
8
+ * it under the terms of the GNU General Public License as published by
9
+ * the Free Software Foundation; either version 2 of the License, or
10
+ * (at your option) any later version.
11
+ *
12
+ * This program is distributed in the hope that it will be useful,
13
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ * GNU General Public License for more details.
16
+ *
17
+ * You should have received a copy of the GNU General Public License
18
+ * along with this program; if not, write to the Free Software
19
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
+ */
21
+
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+ #include <ctype.h>
26
+ #include <errno.h>
27
+
28
+ #include "barcode.h"
29
+
30
+ #define SHRINK_AMOUNT 0.15 /* shrink the bars to account for ink spreading */
31
+
32
+
33
+ /*
34
+ * How do the "partial" and "textinfo" strings work?
35
+ *
36
+ * The first char in "partial" tells how much extra space to add to the
37
+ * left of the bars. For EAN-13, it is used to leave space to print the
38
+ * first digit, other codes may have '0' for no-extra-space-needed.
39
+ *
40
+ * The next characters are alternating bars and spaces, as multiples
41
+ * of the base dimension which is 1 unless the code is
42
+ * rescaled. Rescaling is calculated as the ratio from the requested
43
+ * width and the calculated width. Digits represent bar/space
44
+ * dimensions. Lower-case letters represent those bars that should
45
+ * extend lower than the others: 'a' is equivalent to '1', 'b' is '2' and
46
+ * so on.
47
+ *
48
+ * The "textinfo" string is made up of fields "%lf:%lf:%c" separated by
49
+ * blank space. The first integer is the x position of the character,
50
+ * the second is the font size (before rescaling) and the char item is
51
+ * the charcter to be printed.
52
+ *
53
+ * Both the "partial" and "textinfo" strings may include "-" or "+" as
54
+ * special characters (in "textinfo" the char should be a standalone
55
+ * word). They state where the text should be printed: below the bars
56
+ * ("-", default) or above the bars. This is used, for example, to
57
+ * print the add-5 and add-2 codes to the right of UPC or EAN codes
58
+ * (the add-5 extension is mostly used in ISBN codes.
59
+ */
60
+
61
+
62
+ int Barcode_ps_print(struct Barcode_Item *bc, FILE *f)
63
+ {
64
+ int i, j, k, barlen, printable=1;
65
+ double f1, f2, fsav=0;
66
+ int mode = '-'; /* text below bars */
67
+ double scalef=1, xpos, x0, y0, yr;
68
+ unsigned char *ptr;
69
+ unsigned char c;
70
+
71
+ if (!bc->partial || !bc->textinfo) {
72
+ bc->error = EINVAL;
73
+ return -1;
74
+ }
75
+
76
+
77
+ /*
78
+ * Maybe this first part can be made common to several printing back-ends,
79
+ * we'll see how that works when other ouput engines are added
80
+ */
81
+
82
+ /* First, calculate barlen */
83
+ barlen = bc->partial[0] - '0';
84
+ for (ptr = bc->partial+1; *ptr; ptr++)
85
+ if (isdigit(*ptr))
86
+ barlen += (*ptr - '0');
87
+ else if (islower(*ptr))
88
+ barlen += (*ptr - 'a'+1);
89
+
90
+ /* The scale factor depends on bar length */
91
+ if (!bc->scalef) {
92
+ if (!bc->width) bc->width = barlen; /* default */
93
+ scalef = bc->scalef = (double)bc->width / (double)barlen;
94
+ }
95
+
96
+ /* The width defaults to "just enough" */
97
+ if (!bc->width) bc->width = barlen * scalef +1;
98
+
99
+ /* But it can be too small, in this case enlarge and center the area */
100
+ if (bc->width < barlen * scalef) {
101
+ int wid = barlen * scalef + 1;
102
+ bc->xoff -= (wid - bc->width)/2 ;
103
+ bc->width = wid;
104
+ /* Can't extend too far on the left */
105
+ if (bc->xoff < 0) {
106
+ bc->width += -bc->xoff;
107
+ bc->xoff = 0;
108
+ }
109
+ }
110
+
111
+ /* The height defaults to 80 points (rescaled) */
112
+ if (!bc->height) bc->height = 80 * scalef;
113
+
114
+ #if 0
115
+ /* If too small (5 + text), enlarge and center */
116
+ i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
117
+ if (bc->height < i * scalef ) {
118
+ int hei = i * scalef;
119
+ bc->yoff -= (hei-bc->height)/2;
120
+ bc->height = hei;
121
+ if (bc->yoff < 0) {
122
+ bc->height += -bc->yoff;
123
+ bc->yoff = 0;
124
+ }
125
+ }
126
+ #else
127
+ /* If too small (5 + text), reduce the scale factor and center */
128
+ i = 5 + 10 * ((bc->flags & BARCODE_NO_ASCII)==0);
129
+ if (bc->height < i * scalef ) {
130
+ double scaleg = ((double)bc->height) / i;
131
+ int wid = bc->width * scaleg / scalef;
132
+ bc->xoff += (bc->width - wid)/2;
133
+ bc->width = wid;
134
+ scalef = scaleg;
135
+ }
136
+ #endif
137
+
138
+ /*
139
+ * Ok, then deal with actual ps (eps) output
140
+ */
141
+
142
+ if (!(bc->flags & BARCODE_OUT_NOHEADERS)) { /* spit a header first */
143
+ if (bc->flags & BARCODE_OUT_EPS)
144
+ fprintf(f, "%%!PS-Adobe-2.0 EPSF-1.2\n");
145
+ else
146
+ fprintf(f, "%%!PS-Adobe-2.0\n");
147
+ fprintf(f, "%%%%Creator: libbarcode\n");
148
+ if (bc->flags & BARCODE_OUT_EPS) {
149
+ fprintf(f, "%%%%BoundingBox: %i %i %i %i\n",
150
+ bc->xoff,
151
+ bc->yoff,
152
+ bc->xoff + bc->width + 2* bc->margin,
153
+ bc->yoff + bc->height + 2* bc->margin);
154
+ }
155
+ fprintf(f, "%%%%EndComments\n");
156
+ if (bc->flags & BARCODE_OUT_PS) {
157
+ fprintf(f, "%%%%EndProlog\n\n");
158
+ fprintf(f, "%%%%Page: 1 1\n\n");
159
+ }
160
+ }
161
+
162
+ /* Print some informative comments */
163
+ for (i=0; bc->ascii[i]; i++)
164
+ if (bc->ascii[i] < ' ')
165
+ printable = 0;
166
+
167
+ fprintf(f,"%% Printing barcode for \"%s\", scaled %5.2f",
168
+ printable ? bc->ascii : "<unprintable string>", scalef);
169
+ if (bc->encoding)
170
+ fprintf(f,", encoded using \"%s\"",bc->encoding);
171
+ fprintf(f, "\n");
172
+ fprintf(f,"%% The space/bar succession is represented "
173
+ "by the following widths (space first):\n"
174
+ "%% ");
175
+ for (i=0; i<strlen(bc->partial); i++) {
176
+ unsigned char c = bc->partial[i];
177
+ if (isdigit(c)) putc(c, f);
178
+ if (islower(c)) putc(c-'a'+'1', f);
179
+ if (isupper(c)) putc(c-'A'+'1', f);
180
+ }
181
+ /* open array for "forall" */
182
+ fprintf(f, "\n[\n%% height xpos ypos width"
183
+ " height xpos ypos width\n");
184
+
185
+ xpos = bc->margin + (bc->partial[0]-'0') * scalef;
186
+ for (ptr = bc->partial+1, i=1; *ptr; ptr++, i++) {
187
+ /* special cases: '+' and '-' */
188
+ if (*ptr == '+' || *ptr == '-') {
189
+ mode = *ptr; /* don't count it */ i++; continue;
190
+ }
191
+ /* j is the width of this bar/space */
192
+ if (isdigit (*ptr)) j = *ptr-'0';
193
+ else j = *ptr-'a'+1;
194
+ if (i%2) { /* bar */
195
+ x0 = bc->xoff + xpos + (j*scalef)/2;
196
+ y0 = bc->yoff + bc->margin;
197
+ yr = bc->height;
198
+ if (!(bc->flags & BARCODE_NO_ASCII)) { /* leave space for text */
199
+ if (mode == '-') {
200
+ /* text below bars: 10 points or five points */
201
+ y0 += (isdigit(*ptr) ? 10 : 5) * scalef;
202
+ yr -= (isdigit(*ptr) ? 10 : 5) * scalef;
203
+ } else { /* '+' */
204
+ /* text above bars: 10 or 0 from bottom, and 10 from top */
205
+ y0 += (isdigit(*ptr) ? 10 : 0) * scalef;
206
+ yr -= (isdigit(*ptr) ? 20 : 10) * scalef;
207
+ }
208
+ }
209
+ /* Define an array and then use "forall" (Hans Schou) */
210
+ fprintf(f," [%5.2f %6.2f %6.2f %5.2f]%s",
211
+ yr, x0, y0, (j * scalef) - SHRINK_AMOUNT,
212
+ i%4 == 1 ? " " : "\n");
213
+ }
214
+ xpos += j * scalef;
215
+ }
216
+ fprintf(f,"\n]\t{ {} forall setlinewidth moveto 0 exch rlineto stroke} "
217
+ "bind forall\n");
218
+
219
+ /* Then, the text */
220
+
221
+ mode = '-'; /* reinstantiate default */
222
+ if (!(bc->flags & BARCODE_NO_ASCII)) {
223
+ fprintf(f, "[\n%% char xpos ypos fontsize\n");
224
+ k=0; /* k is the "previous font size" */
225
+ for (ptr = bc->textinfo; ptr; ptr = strchr(ptr, ' ')) {
226
+ while (*ptr == ' ') ptr++;
227
+ if (!*ptr) break;
228
+ if (*ptr == '+' || *ptr == '-') {
229
+ mode = *ptr; continue;
230
+ }
231
+ if (sscanf(ptr, "%lf:%lf:%c", &f1, &f2, &c) != 3) {
232
+ fprintf(stderr, "barcode: impossible data: %s\n", ptr);
233
+ continue;
234
+ }
235
+
236
+ fprintf(f, " [(");
237
+ /* Both the backslash and the two parens are special */
238
+ if (c=='\\' || c==')' || c=='(')
239
+ fprintf(f, "\\%c) ", c);
240
+ else
241
+ fprintf(f, "%c) ", c);
242
+ fprintf(f, "%6.2f %6.2f %5.2f]\n",
243
+ bc->xoff + f1 * scalef + bc->margin,
244
+ mode == '-'
245
+ ? (double)bc->yoff + bc->margin
246
+ : (double)bc->yoff + bc->margin+bc->height - 8*scalef,
247
+ fsav == f2 ? 0.0 : f2 * scalef);
248
+ fsav = f2;
249
+ }
250
+ fprintf(f,"] { {} forall dup 0.00 ne {\n\t"
251
+ "/Helvetica findfont exch scalefont setfont\n"
252
+ " } {pop} ifelse\n"
253
+ " moveto show} bind forall\n");
254
+
255
+
256
+ }
257
+
258
+ fprintf(f,"%% End barcode for \"%s\"\n\n",
259
+ printable ? bc->ascii : "<unprintable string>");
260
+
261
+ if (!(bc->flags & BARCODE_OUT_NOHEADERS)) {
262
+ if (bc->flags & BARCODE_OUT_PS) {
263
+ fprintf(f,"showpage\n");
264
+ fprintf(f, "%%%%Trailer\n\n");
265
+ }
266
+ }
267
+ return 0;
268
+ }
269
+
270
+
271
+
272
+